USocket *usock_accept(int fd, void *cred_p, int clen) { USocket *usock = NULL; struct sockaddr_in addr; socklen_t alen = sizeof(addr); char buf[clen]; Uint32 val, n; while (1) { n = recvfrom(fd, buf, clen, 0, (Sockaddr *)&addr, &alen); if (n < 0) { perror("recvform"); break; } else if (n == clen && memcmp(cred_p, buf, clen) == 0) { usock = create_usock(fd, &addr, cred_p, clen); break; } } if (usock == NULL) return NULL; n = send_accept_msg(fd, &val); if (n == sizeof(val) || val == UMSG_REPLY_ACCEPT) { usock->status |= USOCK_CONNECT; sem_post(&usock->sem); return usock; } sem_post(&usock->sem); usock_close(usock); return NULL; }
void handle_request(struct msg incoming_msg, struct state_info info) { // handle Lamport clocks char diag[200]; update_lamport_recv(incoming_msg.timestamp, info.local_clock); int *my_weight_ptr = g_hash_table_lookup(info.skiers_weights, &info.mytid); int my_weight = *my_weight_ptr; int *sender_weight_ptr = g_hash_table_lookup(info.skiers_weights, &incoming_msg.sender_tid); int sender_weight = *sender_weight_ptr; if (info.phase != PHASE_WAIT_ACCEPTS) { // Always send ACCEPT, don't care about priorities in those phases send_accept_msg(incoming_msg.sender_tid, info); } else { // Send ACCEPT only if: // a) my priority is worse than the sender's priority, // b) or my priority is better but we both can fit // c) or I want the other lift if (*info.my_lift_number != incoming_msg.lift_number) { // I want the other lift send_accept_msg(incoming_msg.sender_tid, info); return; } // my priority is worse else if (*info.my_request_timestamp > incoming_msg.timestamp) { send_accept_msg(incoming_msg.sender_tid, info); return; } else if (*info.my_request_timestamp == incoming_msg.timestamp) { if (incoming_msg.timestamp % 2 == 0) { // admit the heavier skier if (my_weight > sender_weight) { send_accept_msg(incoming_msg.sender_tid, info); return; } } else { // admit the lighter skier if (my_weight <= sender_weight) { send_accept_msg(incoming_msg.sender_tid, info); return; } } } // my priority is better // ELSE if (my_weight + sender_weight <= *info.lift_free) { send_accept_msg(incoming_msg.sender_tid, info); } else { // add the sender to the queue of waiting requests for the lift int *tid = malloc(sizeof(int)); memcpy(tid, &incoming_msg.sender_tid, sizeof(int)); g_queue_push_tail(info.waiting_req_q, tid); int *pushed = g_queue_peek_tail(info.waiting_req_q); sprintf(diag, "*** pushed tid=%d", *pushed); diag_msg(info.mstrtid, info.mytid, diag); } } };