/*
 * main.c
 *
 *  Created on: Oct 29, 2010
 *      Author: jenson
 */

#include
#include
#include
#include
#include
#include
typedef struct _list_args * list_args;
struct _list_args {
    list_t * list;
    int value;
};
pthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER;//全局变量锁
struct timeval begintime;
void * pop_list(void * list) {
    pthread_t tid;
    tid =pthread_self();
    printf("-----thread %d started.----\n",tid);
    if (list != NULL && list_size(list) > 0) {
        if (pthread_mutex_lock(&q_lock) == 0) {
            //while (!list_empty(list)) {
            printf("pop %d\n", *(int *) list_back(list));
            list_pop_back(list);
            //}
            pthread_mutex_unlock(&q_lock);
        }
    } else {
        printf("no data in the list.\n");
    }
    return NULL;
}

void * insert_list(list_args listargs) {
    pthread_t tid;
    tid = pthread_self();
     printf("-----thread %d started.----\n",tid);
    if (listargs != NULL) {
        printf("thread %d begin to insert into the list.\n",tid);
        if (pthread_mutex_lock(&q_lock) == 0) {
            list_push_back(listargs->list,listargs->value);
            pthread_mutex_unlock(&q_lock);
        }
    } else {
        printf("this list is null.\n");
    }

    return NULL;
}

int main() {

    list_t * list = create_list(int);
    pthread_t t1, t2, t3, t4, t5, t6;
    list_args listargs1 = (list_args) malloc(sizeof(list_args));
    list_args listargs2 = (list_args) malloc(sizeof(list_args));
    list_args listargs3 = (list_args) malloc(sizeof(list_args));
    gettimeofday(&begintime, NULL);

    if (listargs1 == NULL) {
        perror("malloc list_args1");
        exit(1);
    }

    if (listargs2 == NULL) {
        perror("malloc list_args2");
        exit(1);
    }
    if (listargs3 == NULL) {
        perror("malloc list_args3");
        exit(1);
    }

    if (list == NULL) {
        perror("create_list");
        exit(1);
    }

    list_init(list);

    listargs1->list = list;
    listargs1->value = 10;
    listargs2->list = list;
    listargs2->value = 11;
    listargs3->list = list;
    listargs3->value = 12;
    int i = 0;
    if (pthread_create(&t1, NULL, insert_list, listargs1) == -1) {
        perror("pthread_create t1");
        exit(1);
    }
    printf("created thread %d\n",t1);
    if (pthread_create(&t2, NULL, insert_list, listargs2) == -1) {
        perror("pthread_create t2");
        exit(1);
    }
    printf("created thread %d\n",t2);
    if (pthread_create(&t3, NULL, insert_list, listargs3) == -1) {
        perror("pthread_create t3");
        exit(1);
    }
    printf("created thread %d\n",t3);
    if (pthread_create(&t4, NULL, pop_list, list) == -1) {
        perror("pthread_create t4");
        exit(1);
    }
    printf("created thread %d\n",t4);
    if (pthread_create(&t5, NULL, pop_list, list) == -1) {
        perror("pthread_create t5");
        exit(1);
    }
    printf("created thread %d\n",t5);
    if (pthread_create(&t6, NULL, pop_list, list) == -1) {
        perror("pthread_create t6");
        exit(1);
    }
    printf("created thread %d\n",t6);
    //    pthread_mutex_lock(&q_lock);
    //    for (i = 0; i < 10; i++) {
    //        list_push_back(list,i);
    //    }
    pthread_mutex_unlock(&q_lock);

    int err = pthread_join(t1, NULL);
    if (err != 0) {
        perror("can't join thread t1\n");
        exit(1);
    }
    printf("thread t1 is joined\n");
    err = pthread_join(t2, NULL);
    if (err != 0) {
        perror("cant'join thread t2\n");
        exit(1);
    }
    printf("thread t2 is joined\n");

    err = pthread_join(t3, NULL);
    if (err != 0) {
        perror("cant'join thread t2\n");
        exit(1);
    }
    printf("thread t3 is joined\n");

    err = pthread_join(t4, NULL);
    if (err != 0) {
        perror("cant'join thread t2\n");
        exit(1);
    }
    printf("thread t4 is joined\n");

    while (!list_empty(list)) {
        printf("%d\t", *(int *) list_front(list));
        list_pop_front(list);
    }

    free(listargs1);
    free(listargs2);
    free(listargs3);
    list_destroy(list);//销毁链表
    pthread_mutex_destroy(&q_lock);//销毁互斥量
    printf("\nmain thread is done\n");
    return 0;
}