void cacheResponse(priqueue_t* q, char* key, void* resp, int size) { queue_item_t* item = (queue_item_t*)malloc(sizeof(queue_item_t)); queue_item_t* tmp = NULL; item->req = strndup(key, strlen(key)); item->resp = resp; item->size = size; item->used = time(NULL); pthread_mutex_lock(&mutex); if(priqueue_insert(q, (void*)item) == -1) { tmp = priqueue_delete_min(q); if(tmp == NULL) { /* Cache size of 0? */ destroyQueueItem(&item); } else { /* Destroy LRU item and insert new one */ destroyQueueItem(&tmp); if(priqueue_insert(q, (void*)item) == -1) { /* Should never happen unless cache size == 0 */ destroyQueueItem(&item); } } } pthread_mutex_unlock(&mutex); }
int main(int argc, char *argv[]){ int port; int serversock; int i = 0; int res = 0; int acceptsock = -1; int num_requests = 0; int* x = NULL; queue_item_t* tmp = NULL; struct sigaction sa; pthread_t threads[MAX_THREADS]; priqueue_t queue, jobs; tdata_t data; pthread_attr_t attr; sem_t semaphore; /* Signal handling */ sa.sa_handler = sigINT_handler; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); /* Basic error-checking */ if(argc < 2) { fprintf(stderr, "Error: No port specified.\n\tUsage: ./proxy <port>\n"); return 1; } port = atoi(argv[1]); if(port < 1000 || port > 30000) { fprintf(stderr, "Error: Port number %d out of range. Please use a port between 1000 and 30000\n", port); return 1; } /* Server setup */ serversock = newServerSocket(argv[1]); if(serversock == -1) { fprintf(stderr, "Error: Could not bind/listen to port %d\n", port); return 1; } /* Attributes */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* Setup synchronization mutex */ pthread_mutex_init(&mutex, NULL); pthread_mutex_init(&hostcheck, NULL); sem_init(&semaphore, 0, 0); /* Implement queue for caching & jobs */ priqueue_init(&queue, MAX_CACHE, comparer, match); priqueue_init(&jobs, MAX_PENDING, compare_jobs, match_jobs); /* Up to 500 waiting jobs */ /* init threads */ data.queue = &queue; data.jobs = &jobs; data.sem = &semaphore; for(i = 0 ; i < MAX_THREADS ; ++i) pthread_create(&threads[i], &attr, connection_handler, (void*)&data); /* The server loop */ while(!done) { x = (int*)malloc(sizeof(int)); if((acceptsock = acceptSocket(serversock)) == -1) { /* If an error occurs or interrupted */ if(!done) fprintf(stderr, "Error: Failed to connect client.\n"); free(x); continue; } *x = acceptsock; pthread_mutex_lock(&job_mutex); res = priqueue_insert(&jobs, (void*)x); pthread_mutex_unlock(&job_mutex); if(res == -1) { closeSocket(acceptsock); free(x); /* Lost (rejected) request */ } else { sem_post(&semaphore); } acceptsock = -1; num_requests++; } closeSocket(serversock); for(i = 0 ; i < MAX_THREADS ; ++i) /* Make sure everything gets through */ sem_post(&semaphore); for(i = 0 ; i < MAX_THREADS ; ++i) pthread_join(threads[i], NULL); printf("%10d total HTTP requests served.\n", num_requests); /* Cleanup queue elements */ for(i = 0 ; i < MAX_CACHE ; ++i) { tmp = (queue_item_t*)priqueue_delete_min(&queue); if(tmp == NULL) break; destroyQueueItem(&tmp); } for(i = 0 ; i < MAX_PENDING ; ++i) { x = (int*)priqueue_delete_min(&jobs); if(x == NULL) break; free(x); } sem_destroy(&semaphore); pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&job_mutex); pthread_mutex_destroy(&hostcheck); pthread_attr_destroy(&attr); priqueue_destroy(&queue); priqueue_destroy(&jobs); return 0; }
int main(int argc, char **argv) { int i, maxnum; unsigned long long t1, t2; priqueue_t *pq, *pqb; data_t *d; if (argc < 2) fatal_error("Usage: %s <num elements to insert>\n", argv[0]); maxnum = atol(argv[1]); if (maxnum <= 0) fatal_error("Usage: %s <num elements to insert> <output file>\n", argv[0]); // Allocate data array data = (data_t*) malloc(sizeof(data_t)*maxnum); if (data == NULL) fatal_error("Unable to allocate memory\n"); // Generate keys for (i = 0; i < maxnum; i++) data[i].key = i; // Create new queue pq = priqueue_new((cmpfunc_t)cmpfunc); if (pq == NULL) fatal_error("Unable to create new priqueue\n"); // Test insert t1 = gettime(); for (i = 0; i < maxnum; i++) { priqueue_insert(pq, &data[i].key, &data[i]); } t2 = gettime(); printf("%d microseconds to insert %d elements\n", (int)(t2-t1), maxnum); // Test delmax t1 = gettime(); for (i = 0; i < maxnum; i++) { d = priqueue_delmax(pq); } t2 = gettime(); printf("%d microseconds to remove %d elements\n", (int)(t2-t1), maxnum); // Test join pqb = priqueue_new((cmpfunc_t)cmpfunc); if (pqb == NULL) fatal_error("Unable to create new priqueue\n"); for (i = 0; i < maxnum/2; i++) priqueue_insert(pq, &data[i].key, &data[i]); for (i = maxnum/2; i < maxnum; i++) priqueue_insert(pqb, &data[i].key, &data[i]); t1 = gettime(); pq = priqueue_join(pq, pqb); t2 = gettime(); printf("%d microseconds to join two queues with %d elements\n", (int)(t2-t1), maxnum); priqueue_destroy(pq); printf("Priority queue destroyed\n"); return 0; }