I'm trying to use a global mutable variable but I can't get.
I am forced to use it because i also have a signal handler (sigaction) to which, as you know, cannot pass parameters.
I saw some example with lazy_static which always use a mutex and in my case is not good.
I tried to use an Option but i cannot get is as mutable.
Could you provide me any example or (maybe) another way to do that?
Thanks in advance.
An atomic type might suit. However, it'll be easier to answer correctly if you tell us more about your use case. What signal are you handling, and what do you want to do when it arrives? What is your program doing while this is happening?
The ctrlc library might be interesting, as it provides a safe wrapper for SIGINT handling.
My signal handler handles SIGCHLD and via siginfo i can get all data about signal, pid etc etc.
These data must be write in this global variable.
Because it is a simply struct, shoud i use AtomicPtr?
Any example?
No, AtomicPtr is for when you want to swap out pointers atomically.
How do you want to store this information (a Vec, etc.) -- and what types do they have?
Generally, this is pretty tricky, since an interrupt is able to interrupt anything happening on the main thread. You may be better off using a channel.
UnitdData is a simple struct which contain vectors, booleans etc etc.
I can write into it without problems.
Now, i cannot pass to signal handler this variable which signature is:
UNITD_DATA will be locked from start to end, i am not able to acquire the lock wherever.
Moreover, use a mutex in a signal handler is a bad idea. The signal can generate theirself in whatever moment taking ownership the current thread, thus, i cannot acquire the lock.
I must globally access to UNITD_DATA as mutable without a mutex.
How could i do?
You could perhaps use that to send an owned value (maybe one that doesn't allocate?) to another thread. That other thread could then acquire a lock or do other things which may depend on the signal handler having returned.
Yeah, actually i have already resolved it just right with a channel.
At this point, another thread will read from the channel the signal information (sig_num, sig_code, sig_pid) and will select the process according the received pid and will restart it if the latter has a channel (Restart property).
My problem was that cannot access to a static global mutable variable from signal handler but from a static channel is possible instead. I used a crossbeam channel but probably a standard library's channel can is good as well.
Does an unbounded channel allocate memory? I think it has to. And:
Is allocating memory okay to do in a signal handler, or will it cause race conditions / UB if the signal handler is called in a wrong moment?
Moreover, an unbounded channel might lead to memory exhaustion if your signals are generated faster than the thread(s) can consume the items from the channel. But not sure if that's a problem.
Yes, it might choose to allocate. In the extreme case, consider what happens if the main thread becomes deadlocked— The channel will need to collect arbitrarily many signal activations to report later, because it has no way of knowing about the deadlock.
If that's not acceptable, you'll need to use some kind of bounded solution that either drops or consolidates signal information if you receive signals too fast. The simplest approach for this would be to use a bounded channel, and send() will return Err(...) if the channel is full.
Of course, I'll try to send the data before via try_send(). If the channel is full then will trace the error into system log or could re-attempt to do (for example max 3 times) after a little timeout (1 second) which should be enough to empty the channel.
You consider that these data (just three int value) will be read and rewrite into specific process channel if the process has been configured as restartable. It will be an operation very fast.
Thanks for collaboration.
Good! I can quietly avoid that above said even if a simple check is not a bad idea.
I have just re-check the api crossbeam::channel - Rust.
I should be ok.
Thanks again.
Not sure what you mean with a simple check. Note that there is still the potential issue of allocating, where I'm not sure if it's okay to allocate in a signal handler.