Mercurial > pidgin
annotate libfaim/txqueue.c @ 1840:00aef397a1fe
[gaim-migrate @ 1850]
reworked some of the proxy stuff so that it's non-blocking now. next thing to do is to get IRC, MSN, Napster, and Jabber to use the new proxy_connect code. After that, Oscar and Yahoo (maybe Zephyr too? not likely)
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Sat, 12 May 2001 01:38:04 +0000 |
| parents | ec31e23aadc7 |
| children |
| rev | line source |
|---|---|
| 1535 | 1 /* |
| 2 * aim_txqueue.c | |
| 3 * | |
| 4 * Herein lies all the mangement routines for the transmit (Tx) queue. | |
| 5 * | |
| 6 */ | |
| 7 | |
| 8 #define FAIM_INTERNAL | |
| 9 #include <aim.h> | |
| 10 | |
| 11 #ifndef _WIN32 | |
| 12 #include <sys/socket.h> | |
| 13 #endif | |
| 14 | |
| 15 /* | |
| 16 * Allocate a new tx frame. | |
| 17 * | |
| 18 * This is more for looks than anything else. | |
| 19 * | |
| 20 * Right now, that is. If/when we implement a pool of transmit | |
| 21 * frames, this will become the request-an-unused-frame part. | |
| 22 * | |
| 23 * framing = AIM_FRAMETYPE_OFT/OSCAR | |
| 24 * chan = channel for OSCAR, hdrtype for OFT | |
| 25 * | |
| 26 */ | |
|
1593
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
27 faim_internal struct command_tx_struct *aim_tx_new(struct aim_session_t *sess, |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
28 struct aim_conn_t *conn, |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
29 unsigned char framing, |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
30 int chan, |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
31 int datalen) |
| 1535 | 32 { |
| 33 struct command_tx_struct *newtx; | |
| 34 | |
| 35 if (!conn) { | |
| 36 faimdprintf(sess, 0, "aim_tx_new: ERROR: no connection specified\n"); | |
| 37 return NULL; | |
| 38 } | |
| 39 | |
| 40 /* For sanity... */ | |
| 41 if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) || (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT)) { | |
| 42 if (framing != AIM_FRAMETYPE_OFT) { | |
| 43 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n"); | |
| 44 return NULL; | |
| 45 } | |
| 46 } else { | |
| 47 if (framing != AIM_FRAMETYPE_OSCAR) { | |
| 48 faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n"); | |
| 49 return NULL; | |
| 50 } | |
| 51 } | |
| 52 | |
| 53 newtx = (struct command_tx_struct *)malloc(sizeof(struct command_tx_struct)); | |
| 54 if (!newtx) | |
| 55 return NULL; | |
| 56 memset(newtx, 0, sizeof(struct command_tx_struct)); | |
| 57 | |
| 58 newtx->conn = conn; | |
| 59 | |
| 60 if(datalen) { | |
| 61 newtx->data = (unsigned char *)malloc(datalen); | |
| 62 newtx->commandlen = datalen; | |
| 63 } else | |
| 64 newtx->data = NULL; | |
| 65 | |
| 66 newtx->hdrtype = framing; | |
| 67 if (newtx->hdrtype == AIM_FRAMETYPE_OSCAR) { | |
| 68 newtx->hdr.oscar.type = chan; | |
| 69 } else if (newtx->hdrtype == AIM_FRAMETYPE_OFT) { | |
| 70 newtx->hdr.oft.type = chan; | |
| 71 newtx->hdr.oft.hdr2len = 0; /* this will get setup by caller */ | |
| 72 } else { | |
| 73 faimdprintf(sess, 0, "tx_new: unknown framing\n"); | |
| 74 } | |
| 75 | |
| 76 return newtx; | |
| 77 } | |
| 78 | |
| 79 /* | |
| 80 * aim_tx_enqeue__queuebased() | |
| 81 * | |
| 82 * The overall purpose here is to enqueue the passed in command struct | |
| 83 * into the outgoing (tx) queue. Basically... | |
| 84 * 1) Make a scope-irrelevent copy of the struct | |
| 85 * 2) Lock the struct | |
| 86 * 3) Mark as not-sent-yet | |
| 87 * 4) Enqueue the struct into the list | |
| 88 * 5) Unlock the struct once it's linked in | |
| 89 * 6) Return | |
| 90 * | |
| 91 * Note that this is only used when doing queue-based transmitting; | |
| 92 * that is, when sess->tx_enqueue is set to &aim_tx_enqueue__queuebased. | |
| 93 * | |
| 94 */ | |
| 95 static int aim_tx_enqueue__queuebased(struct aim_session_t *sess, struct command_tx_struct *newpacket) | |
| 96 { | |
| 97 struct command_tx_struct *cur; | |
| 98 | |
| 99 if (newpacket->conn == NULL) { | |
| 100 faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n"); | |
| 101 newpacket->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); | |
| 102 } | |
| 103 | |
| 104 if (newpacket->hdrtype == AIM_FRAMETYPE_OSCAR) { | |
| 105 /* assign seqnum */ | |
| 106 newpacket->hdr.oscar.seqnum = aim_get_next_txseqnum(newpacket->conn); | |
| 107 } | |
| 108 /* set some more fields */ | |
| 109 newpacket->lock = 1; /* lock */ | |
| 110 newpacket->sent = 0; /* not sent yet */ | |
| 111 newpacket->next = NULL; /* always last */ | |
| 112 | |
| 113 /* see overhead note in aim_rxqueue counterpart */ | |
| 114 if (sess->queue_outgoing == NULL) { | |
| 115 sess->queue_outgoing = newpacket; | |
| 116 } else { | |
| 117 for (cur = sess->queue_outgoing; | |
| 118 cur->next; | |
| 119 cur = cur->next) | |
| 120 ; | |
| 121 cur->next = newpacket; | |
| 122 } | |
| 123 | |
| 124 newpacket->lock = 0; /* unlock so it can be sent */ | |
| 125 | |
| 126 return 0; | |
| 127 } | |
| 128 | |
| 129 /* | |
| 130 * aim_tx_enqueue__immediate() | |
| 131 * | |
| 132 * Parallel to aim_tx_enqueue__queuebased, however, this bypasses | |
| 133 * the whole queue mess when you want immediate writes to happen. | |
| 134 * | |
| 135 * Basically the same as its __queuebased couterpart, however | |
| 136 * instead of doing a list append, it just calls aim_tx_sendframe() | |
| 137 * right here. | |
| 138 * | |
| 139 */ | |
| 140 static int aim_tx_enqueue__immediate(struct aim_session_t *sess, struct command_tx_struct *newpacket) | |
| 141 { | |
| 142 if (newpacket->conn == NULL) { | |
| 143 faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n"); | |
| 144 if (newpacket->data) | |
| 145 free(newpacket->data); | |
| 146 free(newpacket); | |
| 147 return -1; | |
| 148 } | |
| 149 | |
| 150 if (newpacket->hdrtype == AIM_FRAMETYPE_OSCAR) | |
| 151 newpacket->hdr.oscar.seqnum = aim_get_next_txseqnum(newpacket->conn); | |
| 152 | |
| 153 newpacket->lock = 1; /* lock */ | |
| 154 newpacket->sent = 0; /* not sent yet */ | |
| 155 | |
| 156 aim_tx_sendframe(sess, newpacket); | |
| 157 | |
| 158 if (newpacket->data) | |
| 159 free(newpacket->data); | |
| 160 free(newpacket); | |
| 161 | |
| 162 return 0; | |
| 163 } | |
| 164 | |
|
1593
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
165 faim_export int aim_tx_setenqueue(struct aim_session_t *sess, |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
166 int what, |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
167 int (*func)(struct aim_session_t *, struct command_tx_struct *)) |
| 1535 | 168 { |
| 169 if (!sess) | |
| 170 return -1; | |
| 171 | |
| 172 if (what == AIM_TX_QUEUED) | |
| 173 sess->tx_enqueue = &aim_tx_enqueue__queuebased; | |
| 174 else if (what == AIM_TX_IMMEDIATE) | |
| 175 sess->tx_enqueue = &aim_tx_enqueue__immediate; | |
| 176 else if (what == AIM_TX_USER) { | |
| 177 if (!func) | |
| 178 return -1; | |
| 179 sess->tx_enqueue = func; | |
| 180 } else | |
| 181 return -1; /* unknown action */ | |
| 182 | |
| 183 return 0; | |
| 184 } | |
| 185 | |
| 186 faim_internal int aim_tx_enqueue(struct aim_session_t *sess, struct command_tx_struct *command) | |
| 187 { | |
| 188 /* | |
| 189 * If we want to send a connection thats inprogress, we have to force | |
| 190 * them to use the queue based version. Otherwise, use whatever they | |
| 191 * want. | |
| 192 */ | |
| 193 if (command && command->conn && (command->conn->status & AIM_CONN_STATUS_INPROGRESS)) { | |
| 194 return aim_tx_enqueue__queuebased(sess, command); | |
| 195 } | |
| 196 return (*sess->tx_enqueue)(sess, command); | |
| 197 } | |
| 198 | |
| 199 /* | |
| 200 * aim_get_next_txseqnum() | |
| 201 * | |
| 202 * This increments the tx command count, and returns the seqnum | |
| 203 * that should be stamped on the next FLAP packet sent. This is | |
| 204 * normally called during the final step of packet preparation | |
| 205 * before enqueuement (in aim_tx_enqueue()). | |
| 206 * | |
| 207 */ | |
| 208 faim_internal unsigned int aim_get_next_txseqnum(struct aim_conn_t *conn) | |
| 209 { | |
| 210 u_int ret; | |
| 211 | |
| 212 faim_mutex_lock(&conn->seqnum_lock); | |
| 213 ret = ++conn->seqnum; | |
| 214 faim_mutex_unlock(&conn->seqnum_lock); | |
| 215 return ret; | |
| 216 } | |
| 217 | |
| 218 /* | |
| 219 * aim_tx_flushqueue() | |
| 220 * | |
| 221 * This the function is responsable for putting the queued commands | |
| 222 * onto the wire. This function is critical to the operation of | |
| 223 * the queue and therefore is the most prone to brokenness. It | |
| 224 * seems to be working quite well at this point. | |
| 225 * | |
| 226 * Procedure: | |
| 227 * 1) Traverse the list, only operate on commands that are unlocked | |
| 228 * and haven't been sent yet. | |
| 229 * 2) Lock the struct | |
| 230 * 3) Allocate a temporary buffer to store the finished, fully | |
| 231 * processed packet in. | |
| 232 * 4) Build the packet from the command_tx_struct data. | |
| 233 * 5) Write the packet to the socket. | |
| 234 * 6) If success, mark the packet sent, if fail report failure, do NOT | |
| 235 * mark the packet sent (so it will not get purged and therefore | |
| 236 * be attempted again on next call). | |
| 237 * 7) Unlock the struct. | |
| 238 * 8) Free the temp buffer | |
| 239 * 9) Step to next struct in list and go back to 1. | |
| 240 * | |
| 241 */ | |
| 242 faim_internal int aim_tx_sendframe(struct aim_session_t *sess, struct command_tx_struct *cur) | |
| 243 { | |
| 244 int buflen = 0; | |
| 245 unsigned char *curPacket; | |
| 246 | |
| 247 if (!cur) | |
| 248 return -1; /* fatal */ | |
| 249 | |
| 250 cur->lock = 1; /* lock the struct */ | |
| 251 | |
| 252 if (cur->hdrtype == AIM_FRAMETYPE_OSCAR) | |
| 253 buflen = cur->commandlen + 6; | |
| 254 else if (cur->hdrtype == AIM_FRAMETYPE_OFT) | |
| 255 buflen = cur->hdr.oft.hdr2len + 8; | |
| 256 else { | |
| 257 cur->lock = 0; | |
| 258 return -1; | |
| 259 } | |
| 260 | |
| 261 /* allocate full-packet buffer */ | |
| 262 if (!(curPacket = (unsigned char *) malloc(buflen))) { | |
| 263 cur->lock = 0; | |
| 264 return -1; | |
| 265 } | |
| 266 | |
| 267 if (cur->hdrtype == AIM_FRAMETYPE_OSCAR) { | |
| 268 /* command byte */ | |
| 269 curPacket[0] = 0x2a; | |
| 270 | |
| 271 /* type/family byte */ | |
| 272 curPacket[1] = cur->hdr.oscar.type; | |
| 273 | |
| 274 /* bytes 3+4: word: FLAP sequence number */ | |
| 275 aimutil_put16(curPacket+2, cur->hdr.oscar.seqnum); | |
| 276 | |
| 277 /* bytes 5+6: word: SNAC len */ | |
| 278 aimutil_put16(curPacket+4, cur->commandlen); | |
| 279 | |
| 280 /* bytes 7 and on: raw: SNAC data */ /* XXX: ye gods! get rid of this! */ | |
| 281 memcpy(&(curPacket[6]), cur->data, cur->commandlen); | |
| 282 | |
| 283 } else if (cur->hdrtype == AIM_FRAMETYPE_OFT) { | |
| 284 int z = 0; | |
| 285 | |
| 286 z += aimutil_put8(curPacket+z, cur->hdr.oft.magic[0]); | |
| 287 z += aimutil_put8(curPacket+z, cur->hdr.oft.magic[1]); | |
| 288 z += aimutil_put8(curPacket+z, cur->hdr.oft.magic[2]); | |
| 289 z += aimutil_put8(curPacket+z, cur->hdr.oft.magic[3]); | |
| 290 | |
| 291 z += aimutil_put16(curPacket+z, cur->hdr.oft.hdr2len + 8); | |
| 292 z += aimutil_put16(curPacket+z, cur->hdr.oft.type); | |
| 293 | |
| 294 memcpy(curPacket+z, cur->hdr.oft.hdr2, cur->hdr.oft.hdr2len); | |
| 295 } | |
| 296 | |
| 297 /* | |
| 298 * For OSCAR, a full image of the raw packet data now in curPacket. | |
| 299 * For OFT, an image of just the bloated header is in curPacket, | |
| 300 * since OFT allows us to do the data in a different write (yay!). | |
| 301 */ | |
| 302 faim_mutex_lock(&cur->conn->active); | |
| 303 if (send(cur->conn->fd, curPacket, buflen, 0) != buflen) { | |
| 304 faim_mutex_unlock(&cur->conn->active); | |
| 305 cur->sent = 1; | |
| 306 aim_conn_close(cur->conn); | |
| 307 return 0; /* bail out */ | |
| 308 } | |
| 309 | |
| 310 if ((cur->hdrtype == AIM_FRAMETYPE_OFT) && cur->commandlen) { | |
| 311 int curposi; | |
| 312 for(curposi = 0; curposi < cur->commandlen; curposi++) | |
| 313 faimdprintf(sess, 0, "%02x ", cur->data[curposi]); | |
| 314 | |
| 315 if (send(cur->conn->fd, cur->data, cur->commandlen, 0) != (int)cur->commandlen) { | |
| 316 /* | |
| 317 * Theres nothing we can do about this since we've already sent the | |
| 318 * header! The connection is unstable. | |
| 319 */ | |
| 320 faim_mutex_unlock(&cur->conn->active); | |
| 321 cur->sent = 1; | |
| 322 aim_conn_close(cur->conn); | |
| 323 return 0; /* bail out */ | |
| 324 } | |
| 325 | |
| 326 } | |
| 327 | |
| 328 cur->sent = 1; /* mark the struct as sent */ | |
| 329 cur->conn->lastactivity = time(NULL); | |
| 330 | |
| 331 faim_mutex_unlock(&cur->conn->active); | |
| 332 | |
| 333 if (sess->debug >= 2) { | |
| 334 int i; | |
| 335 | |
| 336 faimdprintf(sess, 2, "\nOutgoing packet: (only valid for OSCAR)"); | |
| 337 for (i = 0; i < buflen; i++) { | |
| 338 if (!(i % 8)) | |
| 339 faimdprintf(sess, 2, "\n\t"); | |
| 340 faimdprintf(sess, 2, "0x%02x ", curPacket[i]); | |
| 341 } | |
| 342 faimdprintf(sess, 2, "\n"); | |
| 343 } | |
| 344 | |
| 345 cur->lock = 0; /* unlock the struct */ | |
| 346 | |
| 347 free(curPacket); /* free up full-packet buffer */ | |
| 348 | |
| 349 return 1; /* success */ | |
| 350 } | |
| 351 | |
| 352 faim_export int aim_tx_flushqueue(struct aim_session_t *sess) | |
| 353 { | |
| 354 struct command_tx_struct *cur; | |
| 355 | |
| 356 if (sess->queue_outgoing == NULL) | |
| 357 return 0; | |
| 358 | |
| 359 faimdprintf(sess, 2, "beginning txflush...\n"); | |
| 360 for (cur = sess->queue_outgoing; cur; cur = cur->next) { | |
| 361 /* only process if its unlocked and unsent */ | |
| 362 if (!cur->lock && !cur->sent) { | |
| 363 | |
| 364 if (cur->conn && (cur->conn->status & AIM_CONN_STATUS_INPROGRESS)) | |
| 365 continue; | |
| 366 | |
| 367 /* | |
| 368 * And now for the meager attempt to force transmit | |
| 369 * latency and avoid missed messages. | |
| 370 */ | |
| 371 if ((cur->conn->lastactivity + cur->conn->forcedlatency) >= time(NULL)) { | |
| 372 /* FIXME FIXME -- should be a break! we dont want to block the upper layers */ | |
| 373 sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL)); | |
| 374 } | |
| 375 | |
| 376 /* XXX XXX XXX this should call the custom "queuing" function!! */ | |
| 377 if (aim_tx_sendframe(sess, cur) == -1) | |
| 378 break; | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 /* purge sent commands from queue */ | |
| 383 aim_tx_purgequeue(sess); | |
| 384 | |
| 385 return 0; | |
| 386 } | |
| 387 | |
| 388 /* | |
| 389 * aim_tx_purgequeue() | |
| 390 * | |
| 391 * This is responsable for removing sent commands from the transmit | |
| 392 * queue. This is not a required operation, but it of course helps | |
| 393 * reduce memory footprint at run time! | |
| 394 * | |
| 395 */ | |
| 396 faim_export void aim_tx_purgequeue(struct aim_session_t *sess) | |
| 397 { | |
| 398 struct command_tx_struct *cur = NULL; | |
| 399 struct command_tx_struct *tmp; | |
| 400 | |
| 401 if (sess->queue_outgoing == NULL) | |
| 402 return; | |
| 403 | |
| 404 if (sess->queue_outgoing->next == NULL) { | |
| 405 if (!sess->queue_outgoing->lock && sess->queue_outgoing->sent) { | |
| 406 tmp = sess->queue_outgoing; | |
| 407 sess->queue_outgoing = NULL; | |
| 408 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) | |
| 409 free(tmp->hdr.oft.hdr2); | |
| 410 free(tmp->data); | |
| 411 free(tmp); | |
| 412 } | |
| 413 return; | |
| 414 } | |
| 415 | |
| 416 for(cur = sess->queue_outgoing; cur->next != NULL; ) { | |
| 417 if (!cur->next->lock && cur->next->sent) { | |
| 418 tmp = cur->next; | |
| 419 cur->next = tmp->next; | |
| 420 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) | |
| 421 free(tmp->hdr.oft.hdr2); | |
| 422 free(tmp->data); | |
| 423 free(tmp); | |
| 424 } | |
| 425 cur = cur->next; | |
| 426 | |
| 427 /* | |
| 428 * Be careful here. Because of the way we just | |
| 429 * manipulated the pointer, cur may be NULL and | |
| 430 * the for() will segfault doing the check unless | |
| 431 * we find this case first. | |
| 432 */ | |
| 433 if (cur == NULL) | |
| 434 break; | |
| 435 } | |
| 436 return; | |
| 437 } | |
|
1593
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
438 |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
439 /** |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
440 * aim_tx_cleanqueue - get rid of packets waiting for tx on a dying conn |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
441 * @sess: session |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
442 * @conn: connection that's dying |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
443 * |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
444 * for now this simply marks all packets as sent and lets them |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
445 * disappear without warning. |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
446 * |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
447 * doesn't respect command_tx_struct locks. |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
448 */ |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
449 |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
450 faim_export int aim_tx_cleanqueue(struct aim_session_t *sess, struct aim_conn_t *conn) |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
451 { |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
452 struct command_tx_struct *cur = NULL; |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
453 |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
454 if(!sess || !conn) |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
455 return -1; |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
456 |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
457 /* we don't respect locks here */ |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
458 for(cur = sess->queue_outgoing; cur; cur = cur->next) |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
459 if(cur->conn == conn) |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
460 cur->sent = 1; |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
461 |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
462 return 0; |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
463 } |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
464 |
|
ec31e23aadc7
[gaim-migrate @ 1603]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1535
diff
changeset
|
465 |
