void handle_event(int fd, short, void *v) { bool success; size_t index = (size_t) v; Assert(index < connections.Size()); ConnectData *cdata = connections[index]; Assert(cdata->live); if (cdata->write_buf.size != 0) { success = WritePacket(fd, &cdata->write_buf); if (success) { cdata->write_buf.base = NULL; cdata->write_buf.pos = NULL; cdata->write_buf.size = 0; } } else { size_t length = cdata->read_buf.pos - cdata->read_buf.base; success = ReadPacket(fd, &cdata->read_buf); if (success) { size_t data_length = cdata->read_buf.pos - cdata->read_buf.base - UINT32_LENGTH; Buffer transaction_buf(cdata->read_buf.base + UINT32_LENGTH, data_length); Transaction *t = new Transaction(); if (!t->Read(&transaction_buf)) { logout << "ERROR: Corrupt packet data" << endl; delete t; return; } handling_transaction = true; t->Execute(); cdata->read_buf.pos = cdata->read_buf.base; cdata->read_buf.Ensure(UINT32_LENGTH); cdata->read_buf.pos += UINT32_LENGTH; t->WriteResult(&cdata->read_buf); cdata->write_buf.base = cdata->read_buf.base; cdata->write_buf.pos = cdata->write_buf.base; cdata->write_buf.size = cdata->read_buf.pos - cdata->read_buf.base; cdata->read_buf.pos = cdata->read_buf.base; success = WritePacket(fd, &cdata->write_buf); if (success) { cdata->write_buf.base = NULL; cdata->write_buf.pos = NULL; cdata->write_buf.size = 0; } // watch for initial and final transactions. if (t->IsInitial()) { Assert(!spawn_count.IsSpecified()); received_initial++; } if (t->IsFinal()) { Assert(received_final < received_initial); received_final++; if (received_final == received_initial) { // this was the last client, so cleanup and exit. logout << "Final transaction received, finishing..." << endl << flush; close(server_socket); ClearBlockCaches(); ClearMemoryCaches(); AnalysisFinish(0); } } delete t; handling_transaction = false; } else if ((ssize_t) length == cdata->read_buf.pos - cdata->read_buf.base) { // connection is closed. there is nothing to read so remove the event. event_del(&cdata->ev); close(cdata->fd); cdata->live = false; cdata->read_buf.Reset(0); cdata->write_buf.Reset(0); } } }