void clientSendPacketList(struct client *c) { struct sendPacket *packet; struct conn *send_conn; struct listNode *node, *node2; ssize_t ret; while (isClientNeedSend(c)) { node = listFirst(c->conns); send_conn = listNodeValue(node); while (listLength(send_conn->send_queue)) { node2 = listFirst(send_conn->send_queue); packet = listNodeValue(node2); ret = sendPacket(c, packet); if (ret == -1) { setClientUnvalid(c); return ; } else if (ret == 1) { return ; } ASSERT(ret == 0); removeListNode(send_conn->send_queue, node2); } if (send_conn->ready_send) removeListNode(c->conns, node); } }
SE_Result SE_List_RemoveElement(SE_List* list, SE_Element e) { SE_ListNode* p; SE_ASSERT(list); p = list->head->next; if(p == NULL) return SE_VALID; while(p) { SE_Element d = p->data; if(SE_Element_Compare(d, e) == 0) break; p = p->next; } if(p == NULL) return SE_VALID; removeListNode(list, p); SE_Element_Release(&p->data); SE_Free(p); return SE_VALID; }
void freeClient(struct client *c) { struct listNode *node; if (c->notify) c->notify(c); wstrFree(c->ip); wstrFree(c->name); msgFree(c->req_buf); freeList(c->conns); close(c->clifd); node = searchListKey(Clients, c); deleteEvent(WorkerProcess->center, c->clifd, EVENT_READABLE|EVENT_WRITABLE); if (!node) ASSERT(0); removeListNode(Clients, node); if (listLength(FreeClients) <= 120) { appendToListTail(FreeClients, c); } else { wfree(c); } }
struct client *createClient(int fd, char *ip, int port, struct protocol *p) { struct client *c; struct listNode *node; node = listFirst(FreeClients); if (node == NULL) { c = wmalloc(sizeof(*c)); } else { c = listNodeValue(node); removeListNode(FreeClients, node); appendToListTail(Clients, c); } if (c == NULL) return NULL; c->clifd = fd; c->ip = wstrNew(ip); c->port = port; c->protocol = p; c->conns = createList(); listSetFree(c->conns, (void (*)(void*))connDealloc); c->req_buf = msgCreate(Server.mbuf_size); c->is_outer = 1; c->should_close = 0; c->valid = 1; c->pending = NULL; c->client_data = NULL; c->notify = NULL; c->last_io = Server.cron_time; c->name = wstrEmpty(); createEvent(WorkerProcess->center, c->clifd, EVENT_READABLE, handleRequest, c); getStatVal(StatTotalClient)++; return c; }
void interpretMessage(char* msg, DistNode* node) { MessageHeader *packet = (MessageHeader *)msg; if (packet->type != MSG_TICK) printMessageHeader(packet); // Copy the packet_history to your local_history if message does not come from driver if (packet->type != MSG_TICK) { //TODO, we should find someway to check if the body is actually serialized data if(packet->body_length > 1) { free(node->local_hist); node->local_hist = deserializeListNode(msg + sizeof(MessageHeader)); } } //record last time node receives a message from the master if( packet->source_pid == node->master_pid && packet->type != MSG_404) node->master_comm = node->offset; int true_offset = 0; //only respond to inter node messages if this node is alive if(!node->alive) { if(findListNode(node->local_hist, packet->source_pid) && packet->source_pid != node->pid) { node->msg_count++; sendMessage(packet->source_pid, MSG_404, packet->metadata, 0); } } else { //check message type and then process it appropriately // used to write final node stats to file FILE *fp; char *filename; struct tm *ptm; time_t stop_time; switch (packet->type) { case MSG_TICK: if( time(NULL) - node->start_time >= RUN_TIME) { filename = malloc(64 * sizeof(char)); sprintf(filename, "%d", (int)node->start_time); strcat(filename, ".csv"); stop_time = node->start_time + (node->offset / 1000); ptm = gmtime(&stop_time); while((fp = fopen(filename, "a")) == NULL); fprintf(fp, "%i,%i,%i,%i\n", getpid(), (int)stop_time, node->msg_count, (int)time(NULL)); fclose(fp); printf("Node %d ending. current time: %s\n", getpid(), asctime(ptm)); node->running = 0; } else { node->offset += node->active_drift * 1000; //reset drift if (node->offset - node->prev_offset >= ADJ_TIME) { node->active_drift = node->default_drift; node->prev_offset = node->offset; } } break; case MSG_INIT_RING: while (node->local_hist->pid != node->pid) { enqueue(&(node->local_hist), dequeue(&(node->local_hist))); } enqueue(&(node->local_hist), dequeue(&(node->local_hist))); break; case MSG_ELECTION_E: // Move self to bottom of list if (packet->type != MSG_INIT_RING) { enqueue(&(node->local_hist), dequeue(&(node->local_hist))); } //packet->metadata containst PID of node that initiated election // If you receive E, and you haven't started an election, forward it node->master_pid = 0; if (node->initiated_election == 0) { node->last_sent = MSG_ELECTION_E; node->msg_count++; sendMessage(node->local_hist->pid, MSG_ELECTION_E, packet->metadata, serializeListNode(node->local_hist)); } // Else if you have started an election, determine if the source of this election is you // If it is, you are the coordinator. Send C else if (packet->metadata == node->pid) { node->last_sent = MSG_ELECTION_C; node->msg_count++; sendMessage(node->local_hist->pid, MSG_ELECTION_C, packet->metadata, serializeListNode(node->local_hist)); } // If it is not, only forward the message E if it's source pid is higher than yours else if (packet->metadata > node->pid) { node->last_sent = MSG_ELECTION_E; node->msg_count++; sendMessage(node->local_hist->pid, MSG_ELECTION_E, packet->metadata, serializeListNode(node->local_hist)); } else { // Else drop the election message printf("Node (%i) dropping msg inititated by %i because it lost the tiebreaker\n", node->pid, packet->metadata); } node->election_in_progress = 1; break; case MSG_ELECTION_C: // Move self to bottom of list if (packet->type != MSG_INIT_RING) { enqueue(&(node->local_hist), dequeue(&(node->local_hist))); } // If you receive C, set your coordinator to C and forward the message // If you receive C and you are the coordinator, drop it // metadata contains PID of node that started election if (packet->metadata == node->pid) { printf("Node (%i) has been elected master\n", node->pid); } else { node->last_sent = MSG_ELECTION_C; node->msg_count++; sendMessage(node->local_hist->pid, MSG_ELECTION_C, packet->metadata, serializeListNode(node->local_hist)); } node->master_pid = packet->metadata; node->initiated_election = 0; break; case MSG_GETTIME: node->election_in_progress = 0; node->msg_count++; sendMessage(packet->source_pid, MSG_GETTIME_R, node->offset, 0); break; case MSG_SETTIME: //calculate new drift value true_offset = packet->metadata; node->active_drift += (float)(true_offset - node->offset) / ADJ_TIME; if( node->active_drift <= 0 ) node->active_drift = .5; break; case MSG_EXIT: node->running = 0; break; //response messages case MSG_404: if( node->pid != node->master_pid) { if (packet->source_pid != node->master_pid) { dequeue(&node->local_hist); node->msg_count++; sendMessage(node->local_hist->pid, node->last_sent, packet->metadata, serializeListNode(node->local_hist)); } } else { //master if( --node->resp_count < 0 ) { node->resp_count = 0; --node->max_resp; } ListNode *temp = findListNode(node->local_hist, packet->source_pid); removeListNode(&(node->local_hist),temp, 0); } break; case MSG_GETTIME_R: --node->resp_count; //hold sum of offsets used to calculate avg offset node->metadata += packet->metadata; if(node->resp_count == 0 ) { //only broadcast systemtime if master if( node->pid == node->master_pid) { //all responses received, calculate system time //metadata holds average system time node->metadata = (node->metadata) / (node->max_resp); //send all nodes the average system time ListNode *iter = node->local_hist; while(iter) { node->msg_count++; sendMessage(iter->pid, MSG_SETTIME, node->metadata, 0); iter = iter->next; } node->metadata = 0; } } break; default: break; } } //driver commands, these always go through even if node is dead switch(packet->type) { case CMD_STAT: printDistNode(node); break; case CMD_TIME: printDistNodeTime(node); break; case CMD_KILL: node->alive = 0; break; case CMD_REV: node->alive = 1; break; default: break; } }
void interpretMessage(char* msg, DistNode* node) { MessageHeader *packet = (MessageHeader *)msg; ListNode* temp; // Copy the packet_history to your local_history if message does not come from driver if (packet->type != MSG_TICK) { //TODO, we should find someway to check if the body is actually serialized data if(packet->body_length > 1){ free(node->local_hist); node->local_hist = deserializeListNode(msg + sizeof(MessageHeader)); } } int true_offset = 0; //only respond to inter node messages if this node is alive if(!node->alive) { if(findListNode(node->local_hist, packet->source_pid) && packet->source_pid != node->pid){ node->msg_count++; sendMessage(packet->source_pid, MSG_404, packet->metadata, 0); } } else{ //printList(node->local_hist); //check message type and then process it appropriately // used to write final node stats to file FILE *fp; char *filename; struct tm *ptm; time_t stop_time; switch (packet->type) { case MSG_TICK: if( time(NULL) - node->start_time >= RUN_TIME){ filename = malloc(64 * sizeof(char)); sprintf(filename, "%d", (int)node->start_time); strcat(filename, ".csv"); stop_time = node->start_time + (node->offset / 1000); ptm = gmtime(&stop_time); while((fp = fopen(filename, "a")) == NULL); fprintf(fp, "%i,%i,%i,%i\n", getpid(), (int)stop_time, node->msg_count, (int)time(NULL)); fclose(fp); printf("Node %d ending. current time: %s\n", getpid(), asctime(ptm)); node->running = 0; } else { node->offset += node->active_drift * 1000; //reset drift if (node->offset - node->prev_offset >= ADJ_TIME){ node->active_drift = node->default_drift; node->prev_offset = node->offset; } // Start synching? if (rand() % 10 == 0) { node->start_syn = 1; } } break; case MSG_INIT_RING: while (node->local_hist->pid != node->pid) { enqueue(&(node->local_hist), dequeue(&(node->local_hist))); } enqueue(&(node->local_hist), dequeue(&(node->local_hist))); break; case MSG_GETTIME: node->msg_count++; sendMessage(packet->source_pid, MSG_GETTIME_R, node->offset, 0); break; case MSG_SETTIME: //calculate new drift value true_offset = packet->metadata; node->active_drift += (float)(true_offset - node->offset) / ADJ_TIME; if( node->active_drift <= 0 ) node->active_drift = .5; break; case MSG_EXIT: node->running = 0; break; //response messages case MSG_404: temp = findListNode(node->local_hist, packet->source_pid); if (temp && temp->pid == node->local_hist->pid) { removeListNode(&node->local_hist, temp, 0); } --node->resp_count; //printList(node->local_hist); break; case MSG_GETTIME_R: --node->resp_count; //hold sum of offsets used to calculate avg offset node->metadata += packet->metadata; if(node->resp_count == 0 ){ //only broadcast systemtime if master //all responses received, calculate system time //metadata holds average system time node->metadata = (node->metadata) / 3; node->msg_count+= 3; sendMessage(node->pid, MSG_SETTIME, node->metadata, 0); sendMessage(peek_bottom(node->local_hist)->pid, MSG_SETTIME, node->metadata, 0); sendMessage(node->local_hist->pid, MSG_SETTIME, node->metadata, serializeListNode(node->local_hist)); node->metadata = 0; node->syn = 0; } break; default: break; } } //driver commands, these always go through even if node is dead switch(packet->type){ case CMD_STAT: printDistNode(node); break; case CMD_TIME: printDistNodeTime(node); break; case CMD_KILL: node->alive = 0; break; case CMD_REV: node->alive = 1; break; default: break; } }