static int _network_async_free_netbuf_proc(int tid, unsigned int tick, int id, intptr_t data) { // netbuf is in data netbuffer_put((netbuf)data); return 0; }//end: _network_async_free_netbuf_proc()
void network_disconnect(int32 fd) { SESSION *s = &g_Session[fd]; netbuf b, bn; // Prevent recursive calls // by wrong implemented on disconnect handlers.. and such.. if(s->disconnect_in_progress == true) return; s->disconnect_in_progress = true; // Disconnect Todo: // - Call onDisconnect Handler // - Release all Assigned buffers. // - remove from event system (notifications) // - cleanup session structure // - close connection. // if(s->onDisconnect != NULL && s->type != NST_LISTENER) { s->onDisconnect(fd); } // Read Buffer if(s->read.buf != NULL) { netbuffer_put(s->read.buf); s->read.buf = NULL; } // Write Buffer(s) b = s->write.buf; while(1) { if(b == NULL) break; bn = b->next; netbuffer_put(b); b = bn; } s->write.buf = NULL; s->write.buf_last = NULL; s->write.n_outstanding = 0; s->write.max_outstanding = 0; // Remove from event system. evdp_remove(fd, &s->evdp_data); // Cleanup Session Structure. s->type = NST_FREE; s->data = NULL; // no application level data assigned s->disconnect_in_progress = false; // Close connection close(fd); }//end: network_disconnect()
static bool _onSend(int32 fd){ register SESSION *s = &g_Session[fd]; register netbuf buf, buf_next; register uint32 szNeeded; register int wLen; if(s->type == NST_FREE) return true; // Possible due to multipl non coalsced event notifications // so onSend gets called after disconnect caused by an previous vent. // we can ignore the call to onSend, then. buf = s->write.buf; while(1){ if(buf == NULL) break; buf_next = buf->next; szNeeded = (buf->dataLen - s->write.dataPos); // using th session-local .dataPos member, due to shared write buffer support. // try to write. wLen = write(fd, &buf->buf[s->write.dataPos], szNeeded); if(wLen == 0){ return false; // eof. }else if(wLen == -1){ if(errno == EAGAIN || errno == EWOULDBLOCK) return true; // dont disconnect / try again later. // all other errors. . return false; } // Wrote data.. => szNeeded -= wLen; if(szNeeded > 0){ // still data left .. // s->write.dataPos += wLen; // fix offset. return true; }else{ // this buffer has been written successfully // could be returned to pool. netbuffer_put(buf); s->write.n_outstanding--; // When threadsafe -> Interlocked here. s->write.dataPos = 0; } buf = buf_next; } // okay, // reaching this part means: // while interrupted by break - // which means all buffers are written, nothing left // s->write.buf_last = NULL; s->write.buf = NULL; s->write.n_outstanding = 0; s->write.dataPos = 0; // Remove from event dispatcher (write notification) // evdp_writable_remove(fd, &s->evdp_data); return true; }//end: _onSend()