void* factory_thread(void* arg) { int i = (intptr_t)arg; /*printf("In factory thread %d\n", i);*/ // mutex here int time_wait; while(!stop_thread) { time_wait = rand()%4; printf("\tFactory %d ships candy & waits %ds\n", i, time_wait); //allocate new candy items candy_t* candy_ptr = malloc(sizeof(candy_t)); candy_ptr->factory_number = i; candy_ptr->time_stamp_in_ms = current_time_in_ms(); //insert it to the buffer bbuff_blocking_insert(candy_ptr); //process item into the stats module stats_record_produced(i); //sleep sleep(time_wait); } // When the thread finishes, print the message such as the following (for thread 0): “Candy-factory 0 done" printf("Candy-factory %d done\n", i); pthread_exit(NULL); }
void resend_fin_pkt(void *opaque) { INFO("Resending the ACK in response to the FIN%s\n", ""); packet_t pkt; // Read the packet from the socket. recv_packet(&pkt); uint32_t cur_ms = current_time_in_ms(); uint32_t elapsed_ms = cur_ms - at_select_ms; if (elapsed_ms <= time_av_ms) { time_av_ms -= elapsed_ms; at_select_ms = cur_ms; } else { time_av_ms = 0; } fds.timeout.tv_sec = time_av_ms / 1000; fds.timeout.tv_usec = (time_av_ms % 1000) * 1000; memset(&pkt, 0, sizeof(pkt)); pkt.ack = rwin.smallest_expected_seq; pkt.datalen = 0; pkt.rwinsz = 0; send_packet(&pkt); INFO("Waiting for %d more seconds in the TIME_WAIT state\n", time_av_ms/1000); }
void *factoryFunc(void *p){ int fac = *((int *) p); srand(time(NULL)); int countProduced=0; while(!stop_thread){ int rand_sec = rand()%3; printf("\tFactory %d ships candy & waits %ds\n", fac, rand_sec ); candy_t* candy = malloc(sizeof(candy_t)); candy->factory_number = fac; candy->time_stamp_in_ms = current_time_in_ms(); bbuff_blocking_insert(candy); countProduced++; stats_record_produced(fac); sleep(rand_sec); free(candy); } //printf("candy created by %d = %d\n", fac, countProduced); printf("Candy-factory %d done\n", fac); }
void* kid_thread(void* arg) { int i = (intptr_t)arg; /*printf("In kid thread %d\n", i);*/ //mutex here int time_wait; for(;;) { time_wait = rand()%2; //extract from buffer candy_t* candy_ptr = (candy_t*) bbuff_blocking_extract(); printf("\tKid %d eats candy & waits %ds\n", i, time_wait); //process item into the stats module if(candy_ptr!=NULL) { stats_record_consumed(candy_ptr->factory_number, current_time_in_ms()-candy_ptr->time_stamp_in_ms); } //free the extracted item free(candy_ptr); //sleep sleep(time_wait); } pthread_exit(NULL); }
void send_file(void *opaque) { int portno; struct sockaddr sa; struct sockaddr_in *si = (struct sockaddr_in *) &sa; socklen_t sa_sz = sizeof(sa); packet_t pkt; int r; r = perhaps_recvfrom(sockfd, (void*)&pkt, sizeof(pkt), 0, &sa, &sa_sz); if (r < 0) { if (errno == EINTR || errno == ECONNREFUSED) { // We return from this function in the hope that the next time // 'sockfd' is read ready, we will be invoked again. return; } else { perror("recvfrom"); exit(1); } } packet_ntoh(&pkt, &pkt); pkt.data[pkt.datalen] = '\0'; sscanf(pkt.data, "%d", &portno); const char *serverIP = sa_data_str(&sa); INFO("Server endpoints {1} [%s:%d] & {2} [%s:%d]\n", serverIP, ntohs(si->sin_port), serverIP, portno); /* // Disconnect port association. sa.sa_family = AF_UNSPEC; Connect(sockfd, &sa, sizeof(SA)); // Bind to the port we were originally bound to, and connect this // socket to the new port number that the server sent us. struct sockaddr cli_sa; struct sockaddr_in *cli_si = (struct sockaddr_in*)&cli_sa; memset(&cli_sa, 0, sizeof(cli_sa)); memcpy(&cli_sa, conn->cli_sa, sizeof(struct sockaddr)); cli_si->sin_port = htons(cliport); Bind(sockfd, &cli_sa, (socklen_t)sizeof(struct sockaddr_in)); */ // We open a new socket and dup2() since nothing else seems to be // working on both Linux as well as Solaris. int new_sockfd = Socket(AF_INET, SOCK_DGRAM, 0); dup2(new_sockfd, sockfd); if (conn->is_local) { set_dontroute(sockfd); } // Bind to the port we were originally bound to, and connect this // socket to the new port number that the server sent us. struct sockaddr_in cli_si; memset(&cli_si, 0, sizeof(cli_si)); memcpy(&cli_si, conn->cli_sa, sizeof(struct sockaddr)); cli_si.sin_port = htons(cliport); Bind(sockfd, (struct sockaddr*)&cli_si, (socklen_t)sizeof(struct sockaddr_in)); sa = *(conn->serv_sa); si->sin_port = htons(portno); Connect(sockfd, &sa, sizeof(SA)); // Send an ACK to the server. pkt.flags = FLAG_ACK; pkt.ack = 1; pkt.rwinsz = cargs->sw_size; ++pkt.seq; pkt.datalen = 0; memset(pkt.data, 0, sizeof(pkt.data)); sprintf(pkt.data, "ACK:%d, RWINSZ: %d", pkt.ack, pkt.rwinsz); INFO("Sending %d bytes of data to the server\n", sizeof(pkt)); send_packet(&pkt); // Receive data from the socket till a packet with the FLAG_FIN flag // is received. if (pthread_create(&tid, NULL, (void *) (&consume_packets), (void *) (&rwin)) < 0) { err_sys("Could not spawn the consumer thread to read packets"); } while (1) { VERBOSE("Waiting on recv(2)...%s\n", ""); int r = recv_packet(&pkt); if (r < 0) { // Handle EINTR. if (errno == EINTR) { // Go back to waiting for a packet. continue; } else { if (errno == ECONNREFUSED) { INFO("http://memegenerator.net/instance/29609574%s\n", ""); } perror("recv"); exit(1); } } INFO("Received packet with SEQ#: %u\n", pkt.seq); packet_t *ack_pkt = rwindow_received_packet(&rwin, &pkt); INFO("ACK Packet will be sent with ACK: %u, Window Size: %d\n", ack_pkt->ack, ack_pkt->rwinsz); send_packet(ack_pkt); if (rwindow_received_all(&rwin)) { fdset_remove(&fds, &fds.rev, sockfd); fds.timeout_cb = fin_timeout; fdset_add(&fds, &fds.rev, sockfd, &sockfd, resend_fin_pkt); fds.timeout.tv_sec = 60; fds.timeout.tv_usec = 0; time_av_ms = 60*1000; at_select_ms = current_time_in_ms(); INFO("Entering the TIME_WAIT state%s\n", ""); INFO("File Transfer completed in %d sec\n", current_time_in_ms() / 1000); return; } free(ack_pkt); ack_pkt = NULL; } // while (1) }