From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15180 invoked by alias); 23 Feb 2004 17:43:55 -0000 Mailing-List: contact pthreads-win32-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: pthreads-win32-owner@sources.redhat.com Received: (qmail 15162 invoked from network); 23 Feb 2004 17:43:54 -0000 Received: from unknown (HELO hotmail.com) (65.54.246.17) by sources.redhat.com with SMTP; 23 Feb 2004 17:43:54 -0000 Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC; Mon, 23 Feb 2004 09:43:53 -0800 Received: from 62.245.182.10 by bay2-dav45.bay2.hotmail.com with DAV; Mon, 23 Feb 2004 17:43:53 +0000 X-Originating-IP: [62.245.182.10] X-Originating-Email: [vcotirlea1@hotmail.com] X-Sender: vcotirlea1@hotmail.com From: "vc" To: Subject: problem using pthread_cancel and pthread_mutex_lock Date: Mon, 23 Feb 2004 17:43:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-ID: X-OriginalArrivalTime: 23 Feb 2004 17:43:53.0727 (UTC) FILETIME=[9AB480F0:01C3FA34] X-SW-Source: 2004/txt/msg00012.txt.bz2 Hi all, I am using the pthread library and I'm having a problem while using pthread_cancel and pthread_mutex_lock. Problem description: I start 2 threads: thread1 and thread2. thread1 is doing a pthread_mutex_lock(&mutex), then sleeps for 5 secs and then it is doing a pthread_cancel for the thread2, then is doing a pthread_mutex_unlock(&mutex) Thread2 is doing a pthread_mutex_lock(&mutex), where it stays as the mutex is owned by the thread1, and at this point the cancel is called. Even if in the cleanup procedure of the thread2 I'm doing an pthread_mutex_unlock or not, next time when the thread1 is trying a pthread_mutex_lock(&mutex) it will block and never gets the mutex. Also the pthread_mutex_unlock(&mutex) for the thread2 in the cleanup function fails (ret value is 1) So, my question is: how can a thread cleanly cancel another thread which is waiting in a 'pthread_mutex_lock' call, so that this mutex is available again ? Here is a sample program: ==================== #include #include #include #include #include void cleanup_routine(void *arg); void reader_function(void *arg); void monitor(void *arg); int global_counter=0; pthread_mutex_t my_mutex; int id[2]; pthread_t reader[2]; int cancel_mode; int main(int argc, char *argv[]) { int my_args; int err = 0; cancel_mode = 1; printf("We'll try to cancel with mode ASYNCHRONOUS\n"); id[0] = 1; id[1] = 2; pthread_mutex_init(&my_mutex, NULL); my_args = 1; pthread_create( &reader[0], NULL, (void*)&monitor, (void *) &my_args); Sleep(2000); my_args = 2; pthread_create( &reader[1], NULL, (void*)&reader_function, (void *) &my_args); while(1) { Sleep(1000); } } void monitor (void *arg ) { int retval; printf("Monitor: Entering monitor routine\n\n"); printf("Monitor: monitor is locking thread...\n"); pthread_mutex_lock(&my_mutex); printf("Monitor: monitor is locking thread - okay\n"); Sleep (5000); printf("Monitor: monitor kills pthread 0x%x:\n", (unsigned int) reader[1]); retval = pthread_cancel (reader[1]); printf("Monitor: kill returns %d\n", retval); printf("Monitor: monitor is unlocking thread...\n"); pthread_mutex_unlock(&my_mutex); printf("Monitor: monitor is unlocking thread - okay\n"); printf("Monitor: monitor running\n"); Sleep (3000); printf("Monitor: monitor is locking thread...\n"); pthread_mutex_lock(&my_mutex); // HERE: it will never get the lock! It will hang here! printf("Monitor: monitor is locking thread - okay\n"); Sleep(1000); printf("Monitor: monitor is unlocking thread...\n"); pthread_mutex_unlock(&my_mutex); printf("Monitor: monitor is unlocking thread - okay\n"); } int args; void reader_function (void *arg ) { int i=0; int id, state; int retval; pthread_cleanup_push(cleanup_routine, NULL); retval = pthread_detach (pthread_self()); pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &state); printf("Thread: pthread_setcancelstate: old state was %d\n", state); if (cancel_mode == 1) { pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &state); } id = *(int *) arg; printf("Thread: entered thread %d\n", id); printf("Thread: thread returns: 0x%x\n", (unsigned int) pthread_self()); printf("Thread: testthread is locking thread...\n"); pthread_mutex_lock(&my_mutex); printf("Thread: testthread is locking thread - okay\n"); // HERE: it shouldn't come here as the thread will be canceled by the monitor thread printf("Thread: testthread is unlocking thread...\n"); pthread_mutex_unlock(&my_mutex); printf("Thread: testthread is unlocking thread - okay\n"); printf("Thread: reader_function finished\n"); pthread_cleanup_pop(0); } void cleanup_routine(void *arg) { int ret = 0; printf("ThreadCleanup: cleanup called\n"); Sleep(5000); ret = pthread_mutex_unlock(&my_mutex); printf("ThreadCleanup:Cleanup routine unlock ret = %d\n", ret); printf("ThreadCleanup:waitThread_cleanup done\n"); } The output looks like: ================= We'll try to cancel with mode ASYNCHRONOUS Monitor: Entering monitor routine Monitor: monitor is locking thread... Monitor: monitor is locking thread - okay Thread: pthread_setcancelstate: old state was 0 Thread: entered thread 2 Thread: thread returns: 0x312d80 Thread: testthread is locking thread... Monitor: monitor kills pthread 0x312d80: Monitor: kill returns 0 Monitor: monitor is unlocking thread... ThreadCleanup: cleanup called Monitor: monitor is unlocking thread - okay Monitor: monitor running Monitor: monitor is locking thread... ThreadCleanup:Cleanup routine unlock ret = 1 ThreadCleanup:waitThread_cleanup done So, from the output can be seen that the 1st thread (called monitor) will never be able to gain the mutex again. Sorry for the long post, Any help will be appreciated, Thanks a lot, Viv