[vdr] OT: need help regarding a threading issue

Reinhard Nissl rnissl at gmx.de
Sun Jan 21 23:49:22 CET 2007


Hi,

I'm going nuts on this issue ;-)

Please have a look at this C code:

struct vos_s {
  pthread_mutex_t           trigger_drawing_mutex;
  pthread_cond_t            trigger_drawing;
};

typedef struct vos_s vos_t;

static int interruptable_sleep(vos_t *pobj, int usec_to_sleep)
{
  struct timespec abstime;

  struct timeval now;
  gettimeofday(&now, 0);

  abstime.tv_sec  = now.tv_sec + usec_to_sleep / 1000000;
  abstime.tv_nsec = now.tv_usec * 1000 + (usec_to_sleep % 1000000) * 1000;

  if (abstime.tv_nsec > 1000000000) {
    abstime.tv_nsec -= 1000000000;
    abstime.tv_sec++;
  }

  return pthread_cond_timedwait(&pobj->trigger_drawing,
&pobj->trigger_drawing_mutex, &abstime);
}

static void trigger_drawing(vos_t *pobj)
{
  pthread_mutex_lock(&pobj->trigger_drawing_mutex);
  pthread_cond_signal(&pobj->trigger_drawing);
  pthread_mutex_unlock(&pobj->trigger_drawing_mutex);
}

static vos_t obj;

static void painter()
{
  pthread_mutex_init(&obj.trigger_drawing_mutex, NULL);
  pthread_cond_init(&obj.trigger_drawing, NULL);

  pthread_mutex_lock(&obj.trigger_drawing_mutex);

  while (1) { /* endless loop just for this show case */
    interruptable_sleep(&obj, 20000);
    fprintf(stderr, "paint\n");
  }

  pthread_mutex_unlock(&obj.trigger_drawing_mutex);

  pthread_cond_destroy(&obj.trigger_drawing);
  pthread_mutex_destroy(&obj.trigger_drawing_mutex);
}

static void dispatcher()
{
  while (1) { /* endless loop just for this show case */
    usleep(15000); /* a substitute for "wait for request" */
    fprintf(stderr, ">>> trigger\n");
    trigger_drawing(&obj);
    fprintf(stderr, "<<< trigger\n");
  }
}

Ok, let's now assume that painter() is the code which thread A executes
and dispatcher() is the code which thread B executes. Let's further
assume that thread B accesses only a "valid" obj (i. e. while painter()
is caught in it's endless loop).

The output should then look "like" the following:

paint
paint
>>> trigger
<<< trigger
paint
>>> trigger
paint
<<< trigger
>>> trigger
<<< trigger
paint
paint

The code is working for me in one case, but in another case I can
reproduce an output like that:

paint
paint
>>> trigger
paint
paint
paint
paint

I. e., thread B get's stuck in trigger_drawing() when trying to lock the
mutex.

But I have no idea, why this can happen. Is there anything obvious to
you in the above code, which I didn't take into account?

Thanks in advance.

Bye.
-- 
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl at gmx.de



More information about the vdr mailing list