Releasing resources in pthread_cond_wait()/pthread_cond_timedwait()
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Releasing resources in pthread_cond_wait()/pthread_cond_timedwait()
We know that cancellation signals could be noticed during pthread_cond_wait()/pthread_cond_timedwait(). Now, at this point if a thread gets canceled we could release the resources held by the thread by using cleanup handlers:
Supppose, my codebase has 5 pthread_cond_wait() and each of the call to the pthread_cond_wait() is accompanied by cleanup handlers as shown in the example above.
Now ,let us consider that the thread has got canceled during the call to the 5th pthread_cond_wait(), i.e the thread will have 4 locks held at that point in time.
My question here is as the thread gets canceled during the call to the 5th pthread_cond_wait(), whether all the cleanup handlers will be called at this point in time or only that cleanup handler, registered for the 5th pthread_cond_wait(), will be called.
from the man page of pthread_cleanup_push(3), I would say: YES, all the clean-up handlers should be called IFF the calls to pthread_cleanup_push(3) are nested as below
man 3 pthread_cleanup_push:
Quote:
"These functions manipulate the calling thread's stack of thread-cancellation clean-up handlers. A clean-up handler is a function that is automatically executed when a thread is canceled [...] it might, for example, unlock a mutex so that it becomes available to other threads in the process.
The pthread_cleanup_push() function pushes routine onto the top of the stack of clean-up handlers."
Though, the clean-up stacks are per-thread and not per process, meaning each thread has a separate clean-up stack!
man 3 pthread_cancel:
Quote:
"When a cancellation requested is acted on, the following steps occur for thread (in this order):
1. Cancellation clean-up handlers are popped (in the reverse of the order in which they were pushed) and called.
By saying nested, I meant a schema like the following (pseudo-code):
Releasing resources in pthread_cond_wait()/pthread_cond_timedwait()
Hi Andi,
Thanks for you reply.
In my case, all the cleanup handlers registered through pthread_cleanup_push() may not be in the same lexical context.
I might be registering cleanup handlers involving mutex variable
which does not have global scope.
Do you mean all the registered handlers will be called in this case also?
Regards,
San
Quote:
Originally Posted by ForzaItalia2006
Hey,
from the man page of pthread_cleanup_push(3), I would say: YES, all the clean-up handlers should be called IFF the calls to pthread_cleanup_push(3) are nested as below
man 3 pthread_cleanup_push:
Though, the clean-up stacks are per-thread and not per process, meaning each thread has a separate clean-up stack!
man 3 pthread_cancel:
By saying nested, I meant a schema like the following (pseudo-code):
In my case, all the cleanup handlers registered through pthread_cleanup_push() may not be in the same lexical context.
I might be registering cleanup handlers involving mutex variable
which does not have global scope.
Do you mean all the registered handlers will be called in this case also?
Regards,
San
I think I haven't yet completely understood your scenario. The general theory according to the man pages is that all the registered cleanup-handlers will be called in reversed registration order when the thread gets cancelled.
Regarding the lexical context, I'm not sure if that works. Linux implements the pthread_cleanup_push(3) and pthread_cleanup_pop(3) by the use of macros so that those two functions should/must be in the same context, because pthread_cleanup_push(3) starts an opening brace while pthread_cleanup_pop(3) finishes the section by a closing brace.
Although possibly not possible in the pthread context, you shouldn't in general register a (global) cleanup-handler for a non-global mutex object, because the object might already be destroyed when the cleanup handler gets called.
If my answer isn't really clear, you could possibly post some parts of your code ...
Thanks for your reply. Actually, i am an infant in the field of multi-threading. However, i have understood what i need to do from your replies.
One more thing...my code snippet is somewhat as follows:
pthread_mutex_lock(lock);
-----------------------
There may be some statements here
------------------------
Some api that is a thread cancellation point.
[pthread_cond_wait()/pthread_cond_timedwait()/close() etc.]
--------------------
There may be some statements here
--------------------
pthread_mutex_unlock(lock);
In this case, my understanding is the thread is holding a lock while executing the api that is cancellation point. Now if the thread somehow gets canceled (due to some signal etc.) at this point in time, the lock will never be released and other threads contending for that lock would hang.
So, i want to modify my code as follows:
pthread_cleanup_push(pthread_mutex_unlock, lock);
pthread_mutex_lock(lock);
------------------------------
There may be some statements here
--------------------------------
Some api that is a thread cancellation point.
[pthread_cond_wait()/pthread_cond_timedwait()/close() etc.]
---------------------------
There may be some statements here
---------------------------------
pthread_cleanup_pop(0);
pthread_mutex_unlock(lock);
I want to know whether this is a correct fix.
Regards,
San
Quote:
Originally Posted by ForzaItalia2006
Hey San,
I think I haven't yet completely understood your scenario. The general theory according to the man pages is that all the registered cleanup-handlers will be called in reversed registration order when the thread gets cancelled.
Regarding the lexical context, I'm not sure if that works. Linux implements the pthread_cleanup_push(3) and pthread_cleanup_pop(3) by the use of macros so that those two functions should/must be in the same context, because pthread_cleanup_push(3) starts an opening brace while pthread_cleanup_pop(3) finishes the section by a closing brace.
Although possibly not possible in the pthread context, you shouldn't in general register a (global) cleanup-handler for a non-global mutex object, because the object might already be destroyed when the cleanup handler gets called.
If my answer isn't really clear, you could possibly post some parts of your code ...
- Andi -
Last edited by sanjeebkdeka; 04-07-2010 at 10:27 PM.
Reason: .
Thanks for your reply. Actually, i am an infant in the field of multi-threading. However, i have understood what i need to do from your replies.
One more thing...my code snippet is somewhat as follows:
pthread_mutex_lock(lock);
-----------------------
There may be some statements here
------------------------
Some api that is a thread cancellation point.
[pthread_cond_wait()/pthread_cond_timedwait()/close() etc.]
--------------------
There may be some statements here
--------------------
pthread_mutex_unlock(lock);
In this case, my understanding is the thread is holding a lock while executing the api that is cancellation point. Now if the thread somehow gets canceled (due to some signal etc.) at this point in time, the lock will never be released and other threads contending for that lock would hang.
So, i want to modify my code as follows:
pthread_cleanup_push(pthread_mutex_unlock, lock);
pthread_mutex_lock(lock);
------------------------------
There may be some statements here
--------------------------------
Some api that is a thread cancellation point.
[pthread_cond_wait()/pthread_cond_timedwait()/close() etc.]
---------------------------
There may be some statements here
---------------------------------
In this case, my understanding is the thread is holding a lock while executing the api that is cancellation point. Now if the thread somehow gets canceled (due to some signal etc.) at this point in time, the lock will never be released and other threads contending for that lock would hang.
You shouldn't mix up signal delivery (to threads) and thread cancellation. While signal delivery is implemented by the kill(2) or pthread_kill(3) API-calls, thread cancellation is done by explicitly calling pthread_cancel(3). The thread's behavior of both is also configured differently. Thread cancellation only occurs if the thread(s) enable cancellation and a different thread calls pthread_cancel(3), though it's part of your design and not influenced by external signals.
Quote:
Originally Posted by sanjeebkdeka
So, i want to modify my code as follows:
pthread_cleanup_push(pthread_mutex_unlock, lock);
pthread_mutex_lock(lock);
------------------------------
There may be some statements here
--------------------------------
Some api that is a thread cancellation point.
[pthread_cond_wait()/pthread_cond_timedwait()/close() etc.]
---------------------------
There may be some statements here
---------------------------------
pthread_cleanup_pop(0);
pthread_mutex_unlock(lock);
I want to know whether this is a correct fix.
From a first view, I would say this looks good. When implementing the pthread_cleanup_push/pop(3) functions, you should basically check which API functions (acting upon cancellation requests) are called within your section to get a good overview what needs to be done in the clean-up handlers to really clean-up all used resources. To get a list of cancellation points in API functions, check the man page pthreads(7) and look for 'Cancellation Points'. pthread_cond_wait(3) for example is a cancellation point. By then further looking into the man page of the function, you'll get information about what this function is doing when a thread has a pending cancellation.
I hope that helps to address any of these problems in the future :-)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.