void SendClientBufferList(int session_id,buffer_node *blist) { session_node *s; s = GetSessionByID(session_id); if (s == NULL) { DeleteBufferList(blist); return; } switch (s->state) { case STATE_GAME : SendGameClientBufferList(s,blist,epoch); break; case STATE_SYNCHED : SendGameClientBufferList(s,blist,0); break; case STATE_ADMIN : case STATE_MAINTENANCE : case STATE_TRYSYNC : SendBufferList(s,blist); break; } }
void SessionAddBufferList(session_node *s,buffer_node *blist) { buffer_node *bn,*temp; int length; /* prereq: we must already hold the muxSend for s */ if (s->send_list == NULL) { /* put first node on, then try the compress junk */ s->send_list = blist; blist = blist->next; s->send_list->next = NULL; bn = s->send_list; } else { length = 1; bn = s->send_list; while (bn->next != NULL) { length++; bn = bn->next; } /* dprintf("non-blank send list len %i\n",length); */ /* if currently backed up more than MAX_SESSION_BUFFER_LIST_LEN, then don't waste any more memory on them */ if (length > MAX_SESSION_BUFFER_LIST_LEN) { //dprintf("SessionAddBufferList deleting because buffer list too long %i\n",s->session_id); DeleteBufferList(blist); return; } } /* simple approach: set bn->next to blist. However, this can use up a ton of buffers, when the amount of data to be sent is small. So do a couple discreet checks, and perhaps memcpy's. */ while (blist != NULL && blist->len_buf < (bn->size_prebuf - bn->len_buf - HEADERBYTES)) { /* dprintf("squeezing %i in %i\n",blist->len_buf,bn->size_buf-bn->len_buf); */ memcpy(bn->buf+bn->len_buf,blist->buf,blist->len_buf); bn->len_buf += blist->len_buf; temp = blist->next; DeleteBuffer(blist); blist = temp; } bn->next = blist; }
// called in main thread // XXX: identical to windows version void InterfaceSendBufferList(buffer_node *blist) { buffer_node *bn; bn = blist; while (bn != NULL) { InterfaceAddAdminBuffer(bn->buf,bn->len_buf); bn = bn->next; } DeleteBufferList(blist); }
void SendBufferList(session_node *s,buffer_node *blist) { buffer_node *bn; if (s->conn.type == CONN_CONSOLE) { InterfaceSendBufferList(blist); return; } if (!s->connected || s->hangup) { DeleteBufferList(blist); return; } if (WaitForSingleObject(s->muxSend,10000) != WAIT_OBJECT_0) { eprintf("SendBufferList couldn't get session %i muxSend\n",s->session_id); return; } if (s->send_list == NULL) { /* if nothing in queue, try to send right now */ while (blist != NULL) { if (send(s->conn.socket,blist->buf,blist->len_buf,0) == SOCKET_ERROR) { if (GetLastError() != WSAEWOULDBLOCK) { if (!ReleaseMutex(s->muxSend)) eprintf("File %s line %i release of non-owned mutex\n",__FILE__,__LINE__); /* eprintf("SendBufferList got send error %i\n",GetLastError()); */ DeleteBufferList(blist); HangupSession(s); return; } /* dprintf("%i adding to buffer list\n",s->session_id); */ SessionAddBufferList(s,blist); break; } else { transmitted_bytes += blist->len_buf; bn = blist->next; DeleteBuffer(blist); blist = bn; } } } else { SessionAddBufferList(s,blist); } if (!ReleaseMutex(s->muxSend)) eprintf("File %s line %i release of non-owned mutex\n",__FILE__,__LINE__); }
void CloseSession(int session_id) { session_node *s; s = GetSessionByID(session_id); if (s == NULL) { eprintf("CloseSession can't find session %i\n",session_id); return; } if (!s->connected) { eprintf("CloseSession can't close unconnected session %i\n", s->session_id); return; } EnterSessionLock(); s->connected = False; if (!s->exiting_state) /* if a write error occurred during an exit, don't */ ExitSessionState(s); /* go into infinite loop */ if ((s->state != STATE_MAINTENANCE) && (s->account == NULL)) lprintf("CloseSession closing session with no account from %s\n", s->conn.name); else { AccountLogoff(s->account); if (s->account != NULL) lprintf("CloseSession/4 logging off %i\n",s->account->account_id); } s->account = NULL; InterfaceLogoff(s); if (s->conn.type == CONN_SOCKET) { if (WaitForSingleObject(s->muxSend,10000) != WAIT_OBJECT_0) eprintf("CloseSession couldn't get session %i muxSend\n",s->session_id); else { DeleteBufferList(s->send_list); s->send_list = NULL; /* no need to release mutex... we're closing it */ /* if (!ReleaseMutex(s->muxSend)) eprintf("File %s line %i release of non-owned mutex\n",__FILE__,__LINE__); */ } if (WaitForSingleObject(s->muxReceive,10000) != WAIT_OBJECT_0) eprintf("CloseSession couldn't get session %i muxReceive\n",s->session_id); else { DeleteBufferList(s->receive_list); s->receive_list = NULL; /* no need to release mutex... we're closing it */ /* if (!ReleaseMutex(s->muxReceive)) eprintf("File %s line %i release of non-owned mutex\n",__FILE__,__LINE__); */ } if (!CloseHandle(s->muxSend)) eprintf("CloseSession error (%s) closing send mutex %i in session %i\n", GetLastErrorStr(),s->muxSend,s->session_id); if (!CloseHandle(s->muxReceive)) eprintf("CloseSession error (%s) closing receive mutex %i in session %i\n", GetLastErrorStr(),s->muxReceive,s->session_id); CloseConnection(s->conn); } s->session_id = -1; s->state = -1; LeaveSessionLock(); }
void ClearPacket() { DeleteBufferList(blist); blist = NULL; }