On Thu, 2007-06-07 at 15:49 +0200, Anders Blomdell wrote:
> As per request from discussions in
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=241780
> a patch against git.
Yes, on closer inspection this version does look ok.
Let me think about it for a little while in case I missed something.
Ian
>
> Best regards
>
> Anders Blomdell
> plain text document attachment (alarm_handler.patch)
> --- autofs/lib/alarm.c 2007-06-07 15:05:03.000000000 +0200
> +++ /usr/src/autofs/autofs.patched/lib/alarm.c 2007-06-07
> 15:08:29.000000000 +0200
> @@ -28,16 +28,16 @@
>
> #define alarm_lock() \
> do { \
> - int _alm_lock = pthread_mutex_lock(&mutex); \
> - if (_alm_lock) \
> - fatal(_alm_lock); \
> + int status = pthread_mutex_lock(&mutex); \
> + if (status) \
> + fatal(status); \
> } while (0)
>
> #define alarm_unlock() \
> do { \
> - int _alm_unlock = pthread_mutex_unlock(&mutex); \
> - if (_alm_unlock) \
> - fatal(_alm_unlock); \
> + int status = pthread_mutex_unlock(&mutex); \
> + if (status) \
> + fatal(status); \
> } while (0)
>
> void dump_alarms(void)
> @@ -168,87 +168,65 @@
> static void *alarm_handler(void *arg)
> {
> struct list_head *head;
> - struct timespec expire;
> - time_t now;
> int status;
> -
> +
> alarm_lock();
>
> head = &alarms;
>
> while (1) {
> - struct alarm *current;
> -
> - /*
> - * If the alarm list is empty, wait until an alarm is
> - * added.
> - */
> - while (list_empty(head)) {
> + if (list_empty(head)) {
> + /* No alarms, wait for one to be added */
> status = pthread_cond_wait(&cond, &mutex);
> if (status)
> fatal(status);
> - }
> -
> - current = list_entry(head->next, struct alarm, list);
> -
> - now = time(NULL);
> -
> - if (current->time <= now) {
> - struct autofs_point *ap;
> -
> - list_del(¤t->list);
> -
> - if (current->cancel) {
> - free(current);
> - continue;
> - }
> -
> - ap = current->ap;
> - free(current);
> - alarm_unlock();
> -
> - state_mutex_lock(ap);
> - nextstate(ap->state_pipe[1], ST_EXPIRE);
> - state_mutex_unlock(ap);
> -
> - alarm_lock();
> - continue;
> - }
> -
> - expire.tv_sec = current->time;
> - expire.tv_nsec = 0;
> -
> - while (1) {
> - struct autofs_point *ap;
> - struct alarm *next;
> -
> - status = pthread_cond_timedwait(&cond, &mutex, &expire);
> - if (status && status != ETIMEDOUT)
> - fatal(status);
> -
> - next = list_entry(head->next, struct alarm, list);
> - if (next->cancel) {
> - list_del(&next->list);
> - free(next);
> - break;
> + } else {
> + struct alarm *first;
> + time_t now;
> +
> + first = list_entry(head->next, struct alarm, list);
> +
> + now = time(NULL);
> +
> + if (first->time > now) {
> + /* Wait for alarm to trigger or a new alarm
> + to be added */
> + struct timespec expire;
> +
> + expire.tv_sec = first->time;
> + expire.tv_nsec = 0;
> +
> + status = pthread_cond_timedwait(&cond, &mutex,
> + &expire);
> + if (status && status != ETIMEDOUT)
> + fatal(status);
> + } else {
> + /* First alarm has triggered, run it */
> + struct autofs_point *ap;
> +
> + list_del(&first->list);
> + ap = first->ap;
> + if (!first->cancel) {
> + /* We need to unlock the alarm list
> + in case some other thread holds
> + the state_mutex_lock(ap), and is
> + currently trying to do some
> + alarm_* function (i.e if we don't
> + unlock, we might deadlock) */
> + alarm_unlock();
> +
> + state_mutex_lock(ap);
> + nextstate(ap->state_pipe[1],
> + ST_EXPIRE);
> + state_mutex_unlock(ap);
> +
> + alarm_lock();
> + }
> + free(first);
> }
> -
> - if (next != current)
> - break;
> -
> - list_del(¤t->list);
> - ap = current->ap;
> - free(current);
> - alarm_unlock();
> -
> - state_mutex_lock(ap);
> - nextstate(ap->state_pipe[1], ST_EXPIRE);
> - state_mutex_unlock(ap);
> -
> - alarm_lock();
> - break;
> }
> }
> + /* Will never come here, so alarm_unlock is not necessary */
> }
>
> int alarm_start_handler(void)
> _______________________________________________
> autofs mailing list
> [email protected]
> http://linux.kernel.org/mailman/listinfo/autofs
_______________________________________________
autofs mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/autofs