author | Alberto Bertogli
<albertogli@telpin.com.ar> 2005-04-23 23:15:28 UTC |
committer | Alberto Bertogli
<albertogli@telpin.com.ar> 2005-04-23 23:15:28 UTC |
parent | 2a085167f937108f2a940f32f989ef81dd4e39fe |
libfilo.c | +29 | -26 |
diff --git a/libfilo.c b/libfilo.c index 361f7e0..e9c30cd 100644 --- a/libfilo.c +++ b/libfilo.c @@ -319,39 +319,45 @@ int filo_trylock(filock_t *fl, off_t start, off_t len, int mode) static void wait_on(filock_t *fl, off_t start, off_t end, int mode) { - /* all waiter_ranges live on the heap and are created and destroyed - * here. A wr is born here, go to bed in the locking below, until - * wake_up() wakes us up and he dies. While it is manipulated several - * times outside this function, here is the only place where it's - * actually modified. */ - struct waiter_range wr; + /* all waiter_ranges are created and destroyed here. A wr is born + * here, go to bed in the locking below, until wake_up() wakes us up + * and he dies. While it is manipulated several times outside this + * function, here is the only place where it's actually modified; it + * used to be allocated directly on the stack, but maybe some stuff + * assume thread stack is not touched by other threads and it could + * cause some problems in the future; remember: "better safe than + * sorry". */ + struct waiter_range *wr; + wr = malloc(sizeof(struct waiter_range)); /* initialize wr */ - wr.start = start; - wr.end = end; - wr.mode = mode; - wr.owner = pthread_self(); - wr.next = NULL; - wr.prev = NULL; + wr->start = start; + wr->end = end; + wr->mode = mode; + wr->owner = pthread_self(); + wr->next = NULL; + wr->prev = NULL; - sem_init(&(wr.sem), 0, 0); + sem_init(&(wr->sem), 0, 0); /* add to the semi-circular list */ if (fl->waiters == NULL) { - wr.next = NULL; - wr.prev = ≀ - fl->waiters = ≀ + wr->next = NULL; + wr->prev = wr; + fl->waiters = wr; } else { - wr.next = NULL; - wr.prev = fl->waiters->prev; - fl->waiters->prev->next = ≀ - fl->waiters->prev = ≀ + wr->next = NULL; + wr->prev = fl->waiters->prev; + fl->waiters->prev->next = wr; + fl->waiters->prev = wr; } fl_unlock(fl); /* block until some other thread wakes us up */ - sem_wait(&(wr.sem)); + sem_wait(&(wr->sem)); + + free(wr); } static void wake_up(filock_t *fl, off_t start, off_t end) @@ -383,11 +389,8 @@ static void wake_up(filock_t *fl, off_t start, off_t end) wr->next->prev = wr->prev; } - /* it lives on wait_on()'s stack, there's no need to - * free it */ - - /* this will wake the thread up (and the thread will - * destroy wr) */ + /* this will wake the thread up, which is blocked in + * wait_on(), and it will then free wr */ sem_post(&(wr->sem)); return;