On Thu, Oct 14, 2004, Vinu V wrote: > I am using the pth_key_* APIs in my program and I came across a point > where the Pth library is crashing. Don't know whether this is a bug > with Pth or with my program. > This is what I have done. > > int taskVar > main () > { > > int retValue; > pth_mutex_t mutex; > pth_mutex_t cond; > > pth_spawn(PTH_ATTR_DEFAULT, task1, NULL); > > pth_mutex_init(&mutex); > pth_cond_init(&cond); > > pth_key_create(&taskVar, NULL); > pth_key_setdata(taskVar, (int *)123); > retValue = (int)pth_key_getdata(taskVar); > retValue = pth_key_delete(taskVar); > > pth_mutex_acquire(&mutex, 0, NULL); > pth_cond_await(&cond, &mutex, NULL); > pth_mutex_release(&mutex); > > } /* End of main */ > > void *task1(void *arg) > { > pth_mutex_acquire(&mutex, 0, NULL); > pth_cond_notify(&cond, 0); > pth_mutex_release(&mutex); > } > > Here the program crashes at pth_cond_await() in main. > When I comment the pth_key_delete() in main(), then this works perfectly. > > I think this is beacause of a bug in pth_key_delete(). > > int pth_key_delete(pth_key_t key) > { > if (key >= PTH_KEY_MAX) > return pth_error(FALSE, EINVAL); > if (!pth_keytab[key].used) > return pth_error(FALSE, EINVAL); > pth_keytab[key].used = FALSE; > return TRUE; > } > > This function marks the "used" field of the specified key( in this > example this is the index 0 of pth_keytab[] array) as FALSE. But it > is not making the data pointer for this key as NULL. Hence the data > pointer still contains the value 123. > > Now the pth_mutex_acquire internally uses the pth_key_getdata(), which > returns the a a value of 123 which is invalid value for the mutex > event and it crashes when it tries to manipulate this event data. > > Possible FIX. > ------------- > This problem got solved when I cleared the data_value pointer within the > pth_key_delete() function. > > int pth_key_delete(pth_key_t key) > { > if (key >= PTH_KEY_MAX) > return pth_error(FALSE, EINVAL); > if (!pth_keytab[key].used) > return pth_error(FALSE, EINVAL); > > pth_keytab[key].used = FALSE; > pth_current->data_value[key] =(void *)NULL; > > return TRUE; > } > > Please correct me if I am doing anything wrong here ...
Well, the main problem is that a call to pth_key_delete() is only valid after clearing (with "pth_key_setdata(..., NULL)") the data corresponding to this key in *all* threads. Just clearing the key in the *current* thread is not sufficient. Additionally to clearing the data, the corresponding destructor has to be called first, too. The question just is: should pth_key_delete() return with e.g. EBUSY in case any thread still uses data associated with the key or should it instead automatically free all the data associated with it in all threads. I personally think pth_key_delete() should return EBUSY. Any objections? Ralf S. Engelschall [EMAIL PROTECTED] www.engelschall.com ______________________________________________________________________ GNU Portable Threads (Pth) http://www.gnu.org/software/pth/ Development Site http://www.ossp.org/pkg/lib/pth/ Distribution Files ftp://ftp.gnu.org/gnu/pth/ Distribution Snapshots ftp://ftp.ossp.org/pkg/lib/pth/ User Support Mailing List [EMAIL PROTECTED] Automated List Manager (Majordomo) [EMAIL PROTECTED]