Programming This 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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
|
 |
07-12-2004, 11:45 AM
|
#1
|
LQ Newbie
Registered: Jul 2004
Posts: 5
Rep:
|
Multi-threading question (for big time Pros)
Question for Linux Gurus.
I am working on a multithreaded application.
Here are my objectives:
First thread:
...
...
/*Check that my context is valid. Ioctl only if valid context.
Can't protect ioctl with mutex because ioctl might take some time
to get done and in the mean time application might get request from
user to quit and close the application. i.e. a forced close. (Application is playing data). Ioctl on an invalid context might cause kernel to crash. */
mixer_ioctl();
/* Check if context is still valid i.e. ioctl went normally. If it did then lock mutex and do stuff. Otherwise quit. */
...
...
******************************************************
Second thread:
app_close()
{
lock_mutex(context);
...
unlock_mutex(context);
//destroy context.
....
}
*******************************************************
There are two resulting problematic scenarios (one of which I am unable to solve).
1. First thread executes first and call's ioctl. In the mean time second thread gets called and the context gets destroyed. After the ioctl gets done, I am able to detect this in the first thread using a second mutex and I quit happily.
2. First thread gets called first but just before ioctling it gets scheduled out.
Second thread executes and deletes context. When first thread gets scheduled in it tries to ioctl but because context is destroyed, kernel crashes. How do I make sure that context is valid before ioctling here.
I CAN't protect the ioctl call itself with a mutex because I have to allow a potential close while the ioctl is in progress. I can lock mutex and check before ioctl. But then I also have to unlock the mutex. So, if first thread gets scheduled out just after this check I get screwed.
Help Needed badly,
sincere regards,
Prakash
|
|
|
07-12-2004, 01:38 PM
|
#2
|
Member
Registered: Mar 2003
Posts: 804
Rep:
|
i dont believe there is a race free solution. there is no way to atomically release the mutex and call ioctl at the same time. if you were using processes instead of threads, u could use sys V semaphores and use the SEM_UNDO flag. that would let you call ioctl() with the sem locked and not worry about sem staying locked if the process is destroyed. but the SEM_UNDO flag doesn't work with threads - i just checked. maybe for a solution u could do something like:
+use a flag and a mutex to protect access to context
+when the thread is about to call ioctl(), first it locks the mutex and sets the flag
+it releases mutex and calls ioctl
+the other thread locks mutex, checks flag, and sees the context is still busy. it then goes to sleep and checks flag again in X time units
+if the first thread dies in its call to ioctl(), it will never change the flag back. to deal with this, the other thread could sleep and check the flag some max # of times, and then assume the other thread died. this only works if there is some max time limit u can put on the ioctl() call tho.
|
|
|
07-12-2004, 05:55 PM
|
#3
|
LQ Newbie
Registered: Jul 2004
Posts: 5
Original Poster
Rep:
|
Thanks for replying to my question. It looks like to me also that there is no other way out other than sleeping (though I am still trying to avoid using it). But, I guess this should not be a very uncommon problem where two threads can work simultaneously on the same context and one of the threads will eventually destroy the context.
I hope somebody suggests something better.
thanks,
Prakash
|
|
|
07-12-2004, 07:58 PM
|
#4
|
Member
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557
Rep:
|
Can you not get the ioctl() inside the lock and then wake up (this is vague because I don't know the api) the thread doing the ioctl() from app_close()? In particular I would think that any blocking syscall would exit with EINTR if the process receives a signal. Or, can you just kill the ioctl() thread outright before breaking the context?
|
|
|
07-13-2004, 01:21 AM
|
#5
|
Member
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251
Rep:
|
there are certain calls like setcontext and getcontext used for storing and setting user contexts,
if those could be used for some use by u..perhaps...or what you could do ...if those ioctls are to see if the contexts are same before and after the thread getting sched'd in and out...
Actually, I didnt quite get the whole problem, what sort of context is being talked about here, is it the user context? (machine registers, stack,. etc?) or some flag that is being set while this thread is being executed?
when you destroy the other threads context, what do you mean by it...you mean that you destroy the thread with the process knowing nothing about it...or you use pthread_kill or pthread_cancel...cos you could simply set cancellation points in the ioctl thread and cancel the thread if the second thread is able to what it wanted to do correctly..
or you could move the ioctl to the main() thread, cos you definitely cant survive with the main thread not there....
I think what aluser has suggested should be a good way
as an aside...kernel should not crash ..come what may...you must be doing some of your own ioctls without checkin everything....copyfromuser and copytouser must be getting done incorrectly...try doing this stuff as a module before you integrate the whole this with core kernel.
this is quite jumbled up.. sorry for that...
|
|
|
07-13-2004, 10:15 AM
|
#6
|
LQ Newbie
Registered: Jul 2004
Posts: 5
Original Poster
Rep:
|
Sorry for not being very clear on the question (though I think infamous41md got the question bang on target  ).
First a few remarks.
1. I am providing API's so I won't be creating pthreads so cancelling or killing them though possible, is not a great idea.
2. I cannot lock the ioctl call itself. Reason being that the ioctl is playing data and one of the requirements is to force close while ioctl is in progress. If I lock the ioctl then the close cannot be called because it will try to lock the same mutex and will fail.
3. context is nothing but a structure defined by us. It has some application specific data apart from having the mutex. So, this application specific data is stored in memory allocated using malloc. By destroying the context I implied destroying this memory and the mutex. So, both the threads access this common memory area.
Thread synchronisation using signals also doesn't seem to be a solution because then if the First thread (referring to the problem statement) goes in, close will have to wait for it to complete thus defeating the objective of force close.
Thanks,
Prakash.
|
|
|
07-13-2004, 01:06 PM
|
#7
|
Member
Registered: Mar 2003
Posts: 804
Rep:
|
can u explain the force close in more detail? what exactly do u mean by that?
|
|
|
07-13-2004, 01:33 PM
|
#8
|
LQ Newbie
Registered: Jul 2004
Posts: 5
Original Poster
Rep:
|
The First thread is playing data in small frames, each of few millisecs. So, after playing each frame this 'force close' flag is checked. If the flag is set then the rest of the data is not played and the application is closed.
So, the requirement takes shape as following:
The First thread is playing data. But then a request comes to quit immediately and return. This request comes from a second thread that actually calls app_close.
The first thing which app_close will do is to lock global mutex. That is why if I protect the ioctl using this mutex then the close cannot go ahead.
I think this problem is similar to the problem that pthread_cond_wait() solves. pthread_cond_wait() unlocks mutex and then waits atomically. I don't know if doing what pthread_cond_wait() does will help. (though I don't know yet what it does internally).
Please let me know if this is not clear.
Thanks much.
|
|
|
07-13-2004, 01:43 PM
|
#9
|
Member
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251
Rep:
|
i think you can use pthread_cond_wait and pthread_cond_signal for this very purpose...
somethin that infamous said ..just more formally according to pthreads...
|
|
|
07-13-2004, 04:02 PM
|
#10
|
Member
Registered: Mar 2003
Posts: 804
Rep:
|
ok i can think of at least 1 solution now that u have stated the problem:
thread A is locking the mutex and doing the ioctl with the shared data
thread B is going to cancel thread A
A:
lock mutex
check pending quit flag
if pending quit, cleanup, set remove ok flag, pthread_cond_signal() thread B, unlock mutex, exit
do the ioctl() with lock held, handle any interrupted system calls, etc
unlock the mutex
do other stuff.. loop back around?
B:
lock the mutex
set pending quit flag
while(remove_ok == 0)
pthread_cond_wait(pending_cond_var, mutex);
cleanup
|
|
|
07-13-2004, 05:33 PM
|
#11
|
LQ Newbie
Registered: Jul 2004
Posts: 5
Original Poster
Rep:
|
Sorry for not emphasizing on the tricky part enough.
It is possible that the threads run independently. So, app_close may not get called while the other thread is in progress and everything goes on fine. Similarly when close is running then the other thread may not be there. Therefore, close thread will keep on waiting for a signal which will never come.
|
|
|
07-14-2004, 12:25 AM
|
#12
|
Member
Registered: Mar 2003
Posts: 804
Rep:
|
i guess i dont really understand how your program works in detail so it's hard to give u an exact solution, but im positive that thru a flag variable or two and pthread synchronization primitives u can solve it.
|
|
|
07-14-2004, 12:45 AM
|
#13
|
Member
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251
Rep:
|
i think ...i am not sure tho, but if you can see that your thread is dying a premature death, and is aware of it....should be ...after all something failed, then while clearing up it can release the mutex..if it has one and/or signal the condition that shall enable the other thread to do whatever it wants to do..
this type of garbage collection should be done by the thread instead of having the manager thread do all this...
|
|
|
07-14-2004, 12:48 AM
|
#14
|
Member
Registered: Mar 2004
Location: Indiana, USA
Distribution: Fedora, CentOS, Ubuntu, OS/X, Raspbian
Posts: 90
Rep:
|
Real client and Servers vs Threads
This is very interesting. I hope I have read enough to be of help.
I would consider how to make one and only one thread/process own the ioctl interface and responsibilities. All other threads/processes must use a message queue or pipe to send requests to the worker. Testing the pipe or socket connection for a remote partner is fairly easy; and you code rules to shutdown down the worker in a controlled fashion. Also, if a cancel request is in the queue but three messages back, you could scan the whole queue before starting each new request; this would increase your response time to that cancel request.
|
|
|
All times are GMT -5. The time now is 05:52 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|