Fish-Guts
Fish-Guts

Reputation: 336

C - Program crashes or doesn't react when mutex is being used

I have to write a fileserver that allows concurrent operations using a custom protocol.

the preconditions are:

no global locks the physical filesystem must not be touched forks/shm or pthreads must be used.

I though about the following concept:

I'm using prthreads. A new thread is created with every client that connects.

I created a struct to simulate the files:

struct _sFile {
    char *filename;
    size_t size;
    char *content;
    char *location;
    sFile *next;
    pthread_mutex_t *mutex;
};

a linked list of sFile is being used as the filesystem. No directories need to be taken into account

For every operation on files, two locks shall be set; one on the current file and on on the next file. whenever I iterate through the files the locks move together.

I wrote a few functions to iterate through the list:

void iterator_init(iterator *it){
    pthread_mutex_init(it->a->mutex,NULL);
    pthread_mutex_init(it->b->mutex,NULL);
    it->a=NULL;
    it->b=file_list;
    pthread_mutex_lock(it->b->mutex);
}

/*
 * Return the next file in the list or null if at the end.
 * If the end is reached, the iterator is already destoryed.
 */
sFile *iterator_next(iterator *it){
    if (it->a != NULL)
        pthread_mutex_unlock(it->a->mutex);
    if (it->b->next==NULL)
    {
        pthread_mutex_unlock(it->b->mutex);
        return NULL;
    }

    it->a=it->b;
    it->b=it->b->next;
    pthread_mutex_lock(it->b->mutex);
    return it->b;
}

void iterator_destroy(iterator *it){
    if (it->a != NULL)
            pthread_mutex_unlock(it->a->mutex);
    if (it->b != NULL)
            pthread_mutex_unlock(it->b->mutex);
}

I tried to put a lock on the file when my client fires the command LIST. This is my list command:

void cmd_list(int ac, char *av) {
    iterator it;
    iterator_init(&it);
    sFile *list = file_list;
    long num_files = file_count;
    char ack[32];
    sprintf(ack, "ACK %d\n", file_count);
    send(client_sock, ack, (int) strlen(ack), 0);
    sFile *current = list;
    while ((current=iterator_next(&it))!=NULL){
    send(client_sock, current->filename, strlen(current->filename), 0);
}

}

But the application crashes on

interator_init(&it)

in the cmd_create function.

What am I doing wrong? Sometimes, the lock works but the client is waiting endlessly and the comand is being sent to the server unless the client stops.

The source code of the entire application is on

https://github.com/fish-guts/concurrent

Any hints would be appreciated.

Kind regards

Upvotes: 0

Views: 84

Answers (1)

sth
sth

Reputation: 229663

You need to initialize the mutex with pthread_mutex_init() before you can use it. iterator_init() tries to lock the mutex in the struct it gets as a parameter without initializing it.

Upvotes: 2

Related Questions