예제 #1
0
static void *main_alarm_handler(void *ctx)
{
    QALARM *q = (QALARM *)ctx;
    QUEUE_ITEM *item;
    pthread_t tid;
    QTHREAD *qt;

    while ((item = Get_Queue_Item(q->queue))) {
        if (!strcmp(item->action, "Terminate")) {

            /* Send termination signal */
            for (qt = q->threads; qt != NULL; qt = qt->next)
                Add_Queue_Item(qt->queue, "Terminate", NULL, 0);

            /* Wait for termination */
            for (qt = q->threads; qt != NULL; qt = qt->next)
                pthread_join(qt->tid, NULL);

            while (q->threads)
                delete_alarm(q, q->threads->tid);

            Free_Queue_Item(item);
            return NULL;
        } else if (!strcmp(item->action, "Wait")) {
            /* Wait for termination */
            for (qt = q->threads; qt != NULL; qt = qt->next)
                pthread_join(qt->tid, NULL);

            while (q->threads)
                delete_alarm(q, q->threads->tid);

            Free_Queue_Item(item);
            return NULL;
        } else if (!strcmp(item->action, "Destroy")) {
            if (item->sz != sizeof(pthread_t)) {
                Free_Queue_Item(item);
                continue;
            }

            pthread_join(*((pthread_t *)(item->data)), NULL);
            delete_alarm(q, *((pthread_t *)(item->data)));
        } else {
            fprintf(stderr, "Unknown action: %s\n", item->action);
        }

        Free_Queue_Item(item);
    }

    return NULL;
}
예제 #2
0
static void *inner_alarm_handler(void *ctx)
{
    QTHREAD *qt = (QTHREAD *)ctx;
    time_t starttime;
    time_t newtime;
    struct timeval t;
    QUEUE_ITEM *item;

    starttime = time(NULL);
    newtime = qt->timeout;
    while (time(NULL) - starttime < newtime) {
        t.tv_sec = newtime < POLLSEC ? newtime : POLLSEC;
        t.tv_usec = 0;

        select(0, NULL, NULL, NULL, &t);
        newtime = qt->timeout - (time(NULL) - starttime);

        if (!Queue_Empty(qt->queue)) {
            item = Get_Queue_Item(qt->queue);
            if (!strcmp(item->action, "Terminate")) {
                Free_Queue_Item(item);
                return NULL;
            }

            Free_Queue_Item(item);
        }
    }

    qt->cb(qt->data);
    
    if (qt->flags & QALARM_RECUR)
        add_alarm(qt->parent, qt->timeout, qt->cb, qt->data, qt->flags);

    Add_Queue_Item(qt->parent->queue, "Destroy", &(qt->tid), sizeof(pthread_t));

    return NULL;
}
예제 #3
0
int main(int argc, char* argv[]) {
    if(argc != 4) {
        usage();
        exit(1);
    }
    
    init_env();
    init_protocal_buf();
    pthread_mutex_init(&lockDownload, NULL);
    /** init server address **/
    struct sockaddr_in servaddr;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("[%s] is not avalid IP address!\n", argv[1]);
        exit(1);
    }
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    /** check if configure file exists **/
    char conf_full[100];
    strcpy(conf_full, path);
    strcat(conf_full, conf_file);
    if(access(conf_full, 0) == -1) {
        task_flag = NEW_TASK;
        printf("cannot access the file %s\n", conf_full);
        /** init config file, can be expended later for any request **/
        init_conf(conf_full);
    }else {
        task_flag = OLD_TASK;
        printf("access the file %s\n", conf_full);
        
        //TODO continue to send
        config_t *conf_hd = confRead(conf_full);
        sprintf(filename, "%s", confGet(conf_hd, "filename")); 
        load_detail(conf_hd);
        confDestory(conf_hd);
    }

    queue = Initialize_Queue();
    //Add_Queue_Item(queue, "", file_name, 0);
    //Add_Queue_Item(queue, "", file_name, 0);
    //Add_Queue_Item(queue, "", file_name, 0);

    cookLive        = YES;
    soldierLive     = YES;
    receiverLive    = YES;

    /** start Cook thread **/
    pthread_t cook_fd;
    pthread_create(&cook_fd, NULL, cook_mission, path);
    //pthread_join(cook_fd, NULL);

    /** start Receiver thread **/
    pthread_t receiver_id;
    pthread_create(&receiver_id, NULL, receiver, NULL);
    
    //pthread_join(cook_fd, NULL);
    //pthread_join(receiver_id, NULL);
    printf("===========================================================\n");

    struct synack syn_pack;
    syn_pack.thread_num = THREAD_LIMITION;
    syn_pack.file_info.blocksize = BODYLEN;


    while(clientLive){
        soldierLive = YES;
        taskIndex = 0;
        taskArray = NULL;
        filesize = 0;
        block_num = 0;

        QUEUE_ITEM *item = NULL;
        //memset(item, 0, sizeof(QUEUE_ITEM));

        while(!item && clientLive == YES){
            printf("[Main] main thread check queue\n");
            item = Get_Queue_Item(queue);
            if(item){
                printf("[Main] item.filename = %s\n", item->data);
                strcpy(filename, item->data);
                printf("[Main] transmitting: %s \n", filename);
                break;
            }else{
                printf("[Main] Queue empty will check again in 2 seconds...\n");
                sleep(2);
            }
        }
        

        strcpy(syn_pack.file_info.filename, filename);

        /** count filesize **/
        char target_full[100];
        strcpy(target_full, path);
        strcat(target_full, filename);
        int fd = open(target_full, O_RDONLY);
        filesize = get_filesize(fd);
        syn_pack.file_info.filesize = filesize;

        /** count block_num **/
        if(filesize % BODYLEN == 0)
            syn_pack.file_info.block_num = filesize / BODYLEN;
        else
            syn_pack.file_info.block_num = filesize / BODYLEN + 1;
        block_num = syn_pack.file_info.block_num;

        /** make taskArray **/
        taskArray = (int*)malloc(sizeof(int) * block_num);
        memset(taskArray, 0, sizeof(int) * block_num);

        /* count downloaded_block */
        if(task_flag == NEW_TASK) {
            printf("new task\n");
            downloaded_block = 0;
        } else {
            printf("block_num = %d, thread_num = %d, blocksize = %d, filesize = %d\n", syn_pack.file_info.block_num, syn_pack.thread_num, syn_pack.file_info.blocksize, syn_pack.file_info.filesize);

            /** count local global downloaded_block **/
            downloaded_block = 0;
            if(downloaded_block == block_num) {
                printf("download already finished\n");
                continue;
            }
            task_flag = OLD_TASK;
        }

        syn_pack.file_info.downloaded_block = downloaded_block;
        printf("figure out filesize = %d, block_num = %d, downloaded_block = %d\n", filesize, block_num, downloaded_block);

        {
        /**TODO store config info **/
        /*config_t *conf_hd = confRead(conf_full);
          if(conf_hd == NULL)
          {
          printf("conf file null, return \n");
          return 0;
          }
          confSet(conf_hd, "filename", filename);
          confSet(conf_hd, "filesize", filesize);
          store_detail(conf_hd);
          confDestory(conf_hd); */
        }

        /** ask for link with server **/
        struct synack synack_pack = get_new_port(syn_pack, sockfd, (struct sockaddr*)(&servaddr), sizeof(servaddr));
        printf("receive: thread_num = %d, downloaded_block = %d, block_num = %d\n", synack_pack.thread_num, synack_pack.file_info.downloaded_block, synack_pack.file_info.block_num);

        //if(synack_pack == NULL){
            //printf("main get connection failed, exiting...\n");
            //process_end();
            //return 0;
        //}

        /** create subthreads here **/
        task_list = (struct subthread_task *)malloc(sizeof(struct subthread_task) * THREAD_LIMITION);
        int i;
        for(i = 0; i < THREAD_LIMITION; i++) {
            task_list[i].hostname = argv[1];
            task_list[i].port = synack_pack.port[i];

            task_list[i].thread_no = i + 1;
            task_list[i].thread_num = THREAD_LIMITION;

            strcpy(task_list[i].file_info.filename, filename);
            task_list[i].file_info.filesize= filesize;

            task_list[i].file_info.block_num = block_num;
            task_list[i].file_info.blocksize= BODYLEN;

            pthread_create(&ptid[i], NULL, soldier_mission, &task_list[i]);
        }

        signal(SIGINT, process_end);
        signal(SIGKILL, process_end);

        /** print the transmit progress **/
        do{
            sleep(0.1);
            //int percent = (downloaded_block * 100) / block_num;
            /** print_process(percent, 100); **/
        }while(downloaded_block < block_num);

        //soldierLive = NO;   
        
        for(i = 0; i < THREAD_LIMITION; i ++){
            pthread_join(ptid[i], NULL);
        }
        print_process(100, 100); 
        printf("\ndownload finished, exiting...[please wait and not interrupt or power off]\n");
        
        //int j = 0;
        //for(; j < block_num; j ++)
            //printf("%d, ", taskArray[i]);
        //printf("\n");

        free(task_list);
        free(taskArray);
        task_list = NULL;
        taskArray = NULL;
    }

    pthread_mutex_destroy(&lockDownload);
    return 0;
}