I have a signal handler which manipulates a data structure. The data structure's operations aren't atomic. So if two threads/processes are in a critical section at the same time the data structure will be broken.
With threads you can avoid this stuff with semaphores etc.
However, signal handlers work a bit different than threads. If a signal handler is currently manipulating the data structure and during this the signal handler is called again, then the following happens:
It cannot access the data structure because the first signal handler has it locked, which results in a deadlock.
How can I avoid it but still manipulate my data structure? I cannot lose signals either.
The general way to deal with this is: don't. In your signal handler, do as little work as possible - i.e. set/increment a flag to let your program know the signal has been caught, and do the work from the main body of the code.
In the case of incrementing a flag, you might want to have a look at __sync_fetch_and_add() and such in the gcc documentation - do a search for "gcc atomic builtins".
Working on it. It's harder than it sounds to guarantee order AND guarantee safety.
---------- Post updated at 11:18 AM ---------- Previous update was at 11:09 AM ----------
How about this:
basically, rdpos and wrpos get incremented without limit, and % SIGBUF_SIZE is used to wrap their values to inside the array. We do 'unsigned int off=(wrpos-rdpos)' instead of just comparing rdpos and wrpos because, if it hits integer wraparound, rdpos might be near INT_MAX while rdpos is practically zero. Subtracting gets rid of the wraparound.
You shouldn't call get_value in a signal handler, but put_value ought to be safe.
As others said, you should be very wary of doing work in a signal handler. There is a short list of async-signal safe functions. If you're calling anything outside that list, there is already potential for breakage even disregarding that caused by potential data structure corruption.
I would do as recommended, restructure your code to capture the signal and relay it outside the signal handler to be handled by the main thread of execution. You can use, for example, a pipe to put a byte on signaling something has been caught; since write is safe you can call it.
Even the pthread_mutex_lock is async-signal unsafe. Outside of rolling your own async-signal safe locks using atomic variables, I can't suggest anything else. Not to mention that even if you properly protect the data structure, you're still limited in what you can do to it by the lack of safe functions you can call.
If the list is locked and another signal comes in while the list is locked, the 2nd signal handler will go into a deadlock, because the 1st signal handler waits till the 2nd one finishes, hence the list is never freed.
So writing my caught signal info into a pipe works? How much data can a pipe hold? And how do I know how much I have to read from the pipe when n signal handlers wrote something into it?
I just realized that write() doesn't work either, because it can be interrupted before writing something, in which case it throws an error.
Last edited by littlegnome; 12-22-2011 at 09:40 AM..
Here is what i need to do.
@data #has all column wise data so say info for col 1 location for all rows would be in this array
$array = \@data
But i need to create a file which should contain these information in a format for all columns even if i have got no values from some of the index... (0 Replies)
I wonder if I can write my userdefined data structures(ex: a list) to a shared memory segment?
I know, the shm functions get (void*) parameter so I should be able to read and write a list into the shared memory.
may someone inform and clarify me about that, please? (1 Reply)
Rather than re-invent the wheel, I am trying to find a mature C library that provides generic support for lists, trees, etc.
I understand C doesn't formally support "generics", but am aware of a few solutions like GLib and SGLib.
Can anyone kindly recommend what they think is best?... (1 Reply)