/******************************************************************************* * @author : Rohan Jyoti * @name : addToDir * @param : Dictionary to remove from, corresp. key, mChunk to remove * @return : void * @purpose : Remove mChunk to Dictionary ******************************************************************************/ void removeFromDir(dictionary_t *incomingD, char *key, mChunk_t *incomingChunk, queue_t *tKeys) { //if last element, remember to remove the queue and destroy the key from dict queue_t *tQ = (queue_t *)dictionary_get(incomingD, key); if(tQ == NULL) { //doesn't exist return; } else { unsigned int i; for(i=0; i<queue_size(tQ); i++) { mChunk_t *tempC = (mChunk_t *)queue_at(tQ, i); if(tempC->chunkID == incomingChunk->chunkID) if(tempC->chunkSize == incomingChunk->chunkSize) if(tempC->chunkType == incomingChunk->chunkType) if(tempC->data == incomingChunk->data) if(tempC->ip_addr == incomingChunk->ip_addr) if(tempC->port == incomingChunk->port) { queue_remove_at(tQ, i); dictionary_remove(incomingD, key); unsigned int j; for(j=0; j<queue_size(tKeys); j++) if(strcmp(key, (char *)queue_at(tKeys, j)) == 0) queue_remove_at(tKeys, j); break; } } } //next we free incomingChunk if(incomingChunk->data) free(incomingChunk->data); if(incomingChunk->ip_addr) free(incomingChunk->ip_addr); free(incomingChunk); }
/** * Removes all rules which are not descendants of simulated DAG rooted at targets. * * @param rules Queue of rules which is read and modified. * @param targets List of targets which act as roots. * @return Void. */ static void filterOnTargets(queue_t **rules, char **targets){ queue_t *validRules = malloc(sizeof(queue_t)); queue_init(validRules); int idx; //initialize validRules with targets for(idx=0; idx < queue_size(*rules);idx++){ rule_t *curRule = queue_at(*rules, idx); int tarIdx; for(tarIdx=0; targets[tarIdx] != NULL; tarIdx++){ if(strcmp(curRule->target, targets[tarIdx]) == 0){ queue_enqueue(validRules, curRule); queue_remove_at(*rules, idx); idx--; break; } } } //repeated linear search for new valid targets int prevSize = 0; while(prevSize != queue_size(validRules)){ prevSize = queue_size(validRules); for(idx=0; idx < queue_size(*rules); idx++){ rule_t *curRule = queue_at(*rules, idx); if(findMatch(curRule, validRules)){ queue_enqueue(validRules, curRule); queue_remove_at(*rules, idx); idx--; } } } //cleanup old rules queue_iterate(*rules, rule_free_adapter, 0); queue_destroy(*rules); free(*rules); //assign new queue *rules = validRules; }
rule_struct * getRule(){ int i= 0; rule_struct * myRule= NULL; for( ; i < queue_size(&rulesQueue); i++){ myRule= queue_at(&rulesQueue, i); if(queue_size(myRule->rule->deps) == 0 || depsReady(myRule)){ return queue_remove_at(&rulesQueue, i); } } return NULL; }
/******************************************************************************* * @author : Rohan Jyoti * @name : removeFromML * @param : Membership Lis to remove from, payload to remove * @return : void * @purpose : Remove payload from membership list ******************************************************************************/ void removeFromML(queue_t *incomingML, mPayload_t *incomingPayload) { if(queue_size(incomingML) == 0) return; else { char *ip_addr = incomingPayload->IP_address; int tPort = incomingPayload->port; unsigned int i; for(i=0; i<queue_size(incomingML); i++) { mPayload_t *tempPayload = (mPayload_t *)queue_at(incomingML, i); if((strcmp(ip_addr, tempPayload->IP_address) == 0) && (tPort == tempPayload->port)) { queue_remove_at(incomingML, i); return; } } } }
void remove_dep (char * param2) { //printf("Enters\n"); int i,j,k=0; char * hold2 = NULL; rule_t * param1 = NULL; for(j=0;j<queue_size(&q);j++) { param1 = queue_at(&q,j); for(i=0;i<queue_size(param1->deps);i++){ hold2 = queue_at(param1->deps,i); if(strcmp(hold2,param2)==0){ queue_remove_at(param1->deps,i); if(has_deps(param1)==0){ sem_post(&sem_mutex1); k++; } } } } // printf("Jobs created %d",k); return; }
/** * Entry point to parmake. */ int main(int argc, char **argv) { int threads=1; //working threads, additional to main thread char *fname=0; //makefile name char temp=0; //used for whatever char **targets=NULL; //targets array int targetsGiven=0; //targets count queue_init(rules); //queue initialized queue_init(nextRule); //queue initialized queue_init(rulesDup); //queue initialized pthread_t *tid=NULL; //array of thread IDs int i; //loop iterator variable result_t *dummy=NULL; //dummy variable, just in case sem_init(&ruleAvailable, 0, 0); //semaphore initialized lock=PTHREAD_MUTEX_INITIALIZER; //mutex initialized /*threadAvailable*/ //semaphore initialized (later) //part1 while ((temp = getopt(argc, argv, "f:j:")) != -1) { if(temp=='f') { fname=optarg; } else if(temp=='j') { if(optarg!=0) threads=atoi(optarg); } else //Use of option other than f and j { return -1; //unspecified, so I just did same thing as no make file } //I hate having multiple returns, but its faster for now } if(fname==0) { if(access("./makefile", F_OK)==0) fname="./makefile"; else if(access("./Makefile", F_OK)==0) fname="./Makefile"; else return -1; //I hate having multiple returns, but its faster for now } targetsGiven=argc-optind; if(targetsGiven) { targets=malloc((targetsGiven+1)*sizeof(char*)); for(i=0; i<targetsGiven; i++) { targets[i]=argv[optind+i]; } targets[targetsGiven]=NULL; } //part 2 parser_parse_makefile(fname, targets, parsed_new_target, parsed_new_dependency, parsed_new_command); //part 3 and 4 tid=malloc(threads*sizeof(pthread_t)); sem_init(&threadAvailable, 0, threads); for(i=0; i<threads; i++) pthread_create(&tid[i], NULL, runRule, NULL); while(queue_size(rules)) { i=-1; int found=0; rule_t *temp=NULL; while(i<numRules && !found)//numRules is a formality, should always be found { i++; temp=queue_at(q, i); found=1; if(queue_size(temp->deps)!=0) { int j; int k; for(j=0; j<queue_size(rulesDup); j++) { for(k=0; k<queue_size(temp->deps); k++) { if(strcmp(queue_at(temp->deps, k), queue_at(rulesDup, j)->target)==0) { found=0; } } } } } sem_wait(&threadAvailable); pthread_mutex_lock(&lock); //CRITICAL SECTION queue_remove_at(rules, i); queue_enqueue(nextRule, temp); //END CRITICAL SECTION pthread_mutex_unlock(&lock); sem_post(&ruleAvailable); } //set up kickers for threads stuck in wait. Won't always be needed for(i=0; i<threads; i++) { pthread_mutex_lock(&lock); //CRITICAL SECTION queue_enqueue(nextRule, NULL); //END CRITICAL SECTION pthread_mutex_unlock(&lock); sem_post(&ruleAvailable);//waking up waiting threads to kick them } //wait for threads to finish for(i=0; i<threads; i++) { pthread_join(tid[i], (void**)&dummy); } while(queue_size(rulesDup)) { rule_t *temp=queue_dequeue(rulesDup); rule_destroy(temp); free(temp); } queue_destroy(rules); queue_destroy(nextRule); sem_destroy(&threadAvailable); sem_destroy(&ruleAvailable); pthread_mutex_destroy(&lock); if(targetsGiven) { free(targets); } free(tid); return 0; }
//thread function void* runRule(void *ptr) { int kicked=0; int dontRun=0; rule_t *rule=NULL; while(queue_size(rules) && queue_size(nextRule) && !kicked) { sem_wait(&ruleAvailable); pthread_mutex_lock(&lock); //CRITICAL SECTION rule=queue_dequeue(nextRule); //END CRITICAL SECTION pthread_mutex_unlock(&lock); if(rule!=NULL) { int i=0; while(i<queue_size(rule->deps) && !dontRun) { char *dep=queue_dequeue(rule->deps); if(access(dep, F_OK)==0) { stat *stats; stat(dep, stats); time_t thisMod=stats->st_mtime; dontRun=1; int k; for(k=0; k<queue_size(rule->deps); k++) { time_t otherMod=stats->st_mtime; if(otherMod>thisMod) { dontRun=0; } } } i++; } if(!dontRun) { while(queue_size(rule->commands)) { if(system(queue_dequeue(rule->commands))!=0) { exit(1); } } } pthread_mutex_lock(&lock); //CRITICAL SECTION for(i=0; i<queue_size(rulesDup); i++) { queue_t *temp=queue_at(rulesDup, i)->deps; int k; for(k=0; k<queue_size(temp); k++) { if(strcmp(queue_at(temp, k), rule->target)==0) { queue_remove_at(temp, k); } } } //END CRITICAL SECTION pthread_mutex_unlock(&lock); } else { kicked=1; } sem_post(&threadAvailable); } return NULL; }
void process_queues(queue_t *rest_r, queue_t *ready_r, queue_t *complete_t) { int i = 0; while(i < queue_size(rest_r)) { int satify = 1; int dependR = 0; rule_t *rule = queue_at(rest_r, i); int j; for (j = 0; j < queue_size(rule->deps); j++) { char *dep = queue_at(rule->deps, j); int complete = 0; if (isRule(dep)) { int k; for (k = 0; k < queue_size(complete_t); k++) { char *target = queue_at(complete_t, k); if (strcmp(dep, target) == 0) { dependR = 1; complete = 1; break; } } } else { if (access(dep, R_OK) == 0) { complete = 1; } else { fprintf(stderr,"dependency file does not exist!"); exit(1); } } if (!complete) { satify = 0; break; } } if (satify) { if (dependR) { queue_enqueue(ready_r, rule); queue_remove_at(rest_r, i); } else { if (access(rule->target, R_OK) == -1) { queue_enqueue(ready_r, rule); queue_remove_at(rest_r, i); } else { struct stat statbuf; stat(rule->target, &statbuf); time_t rule_time = statbuf.st_mtime; int run = 0; int j; for (j = 0; j < queue_size(rule->deps); j++) { char *dep = queue_at(rule->deps, j); stat(dep, &statbuf); time_t dep_time = statbuf.st_mtime; if (dep_time > rule_time) { run = 1; queue_enqueue(ready_r, rule); queue_remove_at(rest_r, i); break; } } if (!run) { queue_remove_at(rest_r, i); queue_enqueue(complete_t, rule->target); while(queue_size(rule->deps)) { char *dep = queue_dequeue(rule->deps); free(dep); } while(queue_size(rule->commands)) { char *command = queue_dequeue(rule->commands); free(command); } rule_destroy(rule); free(rule); } } } } else { i++; } } }
/* function for pthread_create() to call every time connection is * accepted. Consists of part 3 of MP8 * * @param - pointer to an integer returned by accept representing a * new socket fd to send()/recv() from * @return - NULL */ void* handleConnection(void *clifd) { int clientfd=*((int*)clifd); int keepReceiving, connectionIsAlive=1; //bools unsigned int len; while(connectionIsAlive) { len=0; keepReceiving=1; char buffer[4096]; //PART 3a while(keepReceiving) { len+=recv(clientfd, &(buffer[len]), 4096-len, 0); if(len>=4 && buffer[len-4]=='\r' && buffer[len-3]=='\n' && buffer[len-2]=='\r' && buffer[len-1]=='\n')//if finished receiving, end loop { keepReceiving=0; } if(len==0)//if recv() returned 0, connection was closed { keepReceiving=0; connectionIsAlive=0; } } buffer[len]='\0'; if(connectionIsAlive) { unsigned int i=0, j; //indexes int notEOLine=1; queue_t parsedHeader; queue_init(&parsedHeader); //PART 3b while(i<len) { char lineBuffer[4096]; j=0; notEOLine=1; while(notEOLine) { lineBuffer[j]=buffer[i]; if(lineBuffer[j]=='\n') notEOLine=0; j++; i++; } lineBuffer[j]='\0'; char *temp=malloc(1024*sizeof(char)); if(queue_size(&parsedHeader)==0)//if request line { strcpy(temp, lineBuffer); temp[strlen(temp)-2]='\0'; strcpy(temp, process_http_header_request(temp)); } else { strcpy(temp, lineBuffer); } queue_enqueue(&parsedHeader, ((void*)temp)); } //PART 3cdef char filename[1024]; filename[0]='\0'; strcat(filename, "web"); FILE *file=NULL; char responseln[1024]; responseln[0]='\0'; char contentType[1024]; contentType[0]='\0'; char contentLength[1024]; contentLength[0]='\0'; char connection[1024]; connection[0]='\0'; char *content=malloc(4096*sizeof(char)); content[0]='\0'; //Set responseln, contentType, contentLength, and content if(((char*)queue_at(&parsedHeader, 0))==NULL) //501 Response { //501 sprintf(responseln, "HTTP/1.1 501 %s\r\n", HTTP_501_STRING); strcat(contentType, "Content-Type: text/html\r\n"); sprintf(contentLength, "Content-Length: %d\r\n", (unsigned int)strlen(HTTP_501_CONTENT)); strcat(content, HTTP_501_CONTENT); } else { if(strcmp(((char*)queue_at(&parsedHeader, 0)), "/")==0) { strcat(filename, "/index.html"); } else { strcat(filename, ((char*)queue_at(&parsedHeader, 0))); } file=fopen(filename, "r"); if(file==NULL) { //404 sprintf(responseln, "HTTP/1.1 404 %s\r\n", HTTP_404_STRING); strcat(contentType, "Content-Type: text/html\r\n"); sprintf(contentLength, "Content-Length: %d\r\n", (unsigned int)strlen(HTTP_404_CONTENT)); strcat(content, HTTP_404_CONTENT); } else { //200 sprintf(responseln, "HTTP/1.1 200 %s\r\n", HTTP_200_STRING); int size=strlen(filename); char extention[4]; extention[0]=filename[size-3]; extention[1]=filename[size-2]; extention[2]=filename[size-1]; extention[3]='\0'; if(strcmp(extention, "tml")==0) { strcat(contentType, "Content-Type: text/html\r\n"); } else if(strcmp(extention, "css")==0) { strcat(contentType, "Content-Type: text/css\r\n"); } else if(strcmp(extention, "jpg")==0) { strcat(contentType, "Content-Type: image/jpeg\r\n"); } else if(strcmp(extention, "png")==0) { strcat(contentType, "Content-Type: image/png\r\n"); } else { strcat(contentType, "Content-Type: text/plain\r\n"); } fseek(file, 0, SEEK_END); size=ftell(file); fseek(file, 0, SEEK_SET); sprintf(contentLength, "Content-Length: %d\r\n", size); free(content); content=malloc((size+1)*sizeof(char)); content[0]='\0'; char line[size]; while(fgets(line, size, file) != NULL) { strcat(content, line); } } } i=0; while(i<((unsigned int)queue_size(&parsedHeader))) { if(strcasecmp(((char*)queue_at(&parsedHeader, i)), "Connection: Keep-Alive\r\n")==0) { strcat(connection, "Connection: Keep-Alive\r\n\r\n"); } i++; } if(strlen(connection)==0) { strcat(connection, "Connection: close\r\n\r\n"); connectionIsAlive=0; } //At this point, all parts of the packet are finished. Time to combine and send() char *packet=malloc(( strlen(responseln) + strlen(contentType) + strlen(contentLength) + strlen(connection) + strlen(content) + 1)*sizeof(char)); sprintf(packet, "%s%s%s%s%s", responseln, contentType, contentLength, connection, content); send(clientfd, packet, strlen(packet)*sizeof(char), 0); //CLEANUP while(queue_size(&parsedHeader)) { free(queue_dequeue(&parsedHeader)); } queue_destroy(&parsedHeader); free(content); free(packet); } } close(clientfd); unsigned int i; //CRITICAL ZONE pthread_mutex_lock(lock); for(i=0; i<queue_size(clients); i++) { if(*((int*)queue_at(clients, i))==clientfd) { free(queue_remove_at(clients, i)); } } pthread_mutex_unlock(lock); //END CRITICAL ZONE return NULL; }