inotify 'main loop' - c

I am using inotify with "interupt io" by setting the O_ASYNC flag on the
inotify file descriptor and then using fcntl(inotifyfd, F_SETOWN, getpid())
coupled with a signal(sighandler, SIGIO) call, all from a single process,
in order to set up an inotify file descriptor event handler.
The idea is to have inotify's file descriptor generate the SIGIO signal (via the O_ASYNC flag set) and have teh signal(..) registered handler handle the SIGIO signals
as they are emitted thus avoiding polling the inotify file descriptor.
After the initial setup and signal handler setting the process has nothing to do
and would normally exit.
I need the same process to remain idle after the setup as it acts as a daemon awaiting the SIGIO signals. This is where I am looking for help.
How can I idle the process to take the very least amount of cpu resources?

If your process is going to remain idle until it sees inotify events, then you're severely overcomplicating things.
Just do a normal blocking read() on the inotify file descriptor. Your process will wake up when there's an inotify event. If you want to block-with-timeout, so you can periodically check for something else, use select().
In general, I find that if the answer is "signals" then you've probably asked the wrong question :)

One easy way is to just sleep(3) for a very large amount of time. Since signals wake up the process, you need to put the sleep in a loop:
while(1)
sleep(1000);
The more correct way is probably to use sigsuspend(2):
sigsuspend(NULL);

Just loop on a sigsuspend(); , or even sleep() in this situation. Keep in mind though, that one SIGIO signal might one or more IO events are available.

Related

How to gracefully make a blocking pthread exit from the main thread?

I have a pthread which does an indefinite polling on some file descriptors, with negative timeout parameter.
From the main thread, I would like to be able to indicate to the polling thread that it should exit.
I did some research and found the following approaches:
Use pthread_cancel(): This was discouraged as it might lead to unintended consequences of not clearing any held resources or mutexes
Use a variable as a flag and set it in the main thread. The polling thread checks this flag every iteration and if set, exits by calling pthread_exit(). This approach won't work because my polling thread doesn't loop, but simply blocks indefinitely, waiting on the file descriptors.
Can anyone suggest an elegant solution to this problem ?
Thanks!
ASM
You can create an anonymous pipe with pipe(2) and have the file-descriptor-watching thread add the read end to its polled file descriptors, exiting when that file descriptor reports EOF. The main thread then just closes the write end when it wants the thread to exit.
You can send the blocking thread a signal (e.g. SIGUSR1) with pthread_kill(). The select call should then return a negative value and set errno to EINTR. Don't forget to set a handler for the signal you send.

Running select() socket and timers in the same linux thread

I am writing code on ucLinux for socket communication. I use select() for reading the data on sockets. I also have a 20 msec timer (created using setitimer) running in the same thread for performing a parallel operation. My select function gets blocked each time saying "Interrupted by system call", since it receives the SIGALRM signal issue by the timer on overflow, every 20 msec. I tried restarting the system when EINTR is issued, and run select() again. but this wont help, since i will always receive the SIGALRM by timer every 20 msec. I dont want to ignore this signal since it is used for performing other tasks in the system, but i want to use select without being affected by this signal. Is there any way to handle this? I cannot use functions like timer_create() as these are not supported on the platform I am using. So, I am stuck up with using setitimerfor timer creation. Is there any way I can run both together independently in my code?
What you're doing is pretty weird. Let's face it: timers are an ancient and mostly-obsolete mechanism for doing work. Pretty much everyone these days avoids signals like the plague. There's essentially nothing useful you can do in a signal callback (you certainly can't call anything complicated like malloc for example), so you must have some way to get the timer notification back from the SIGALRM handler to the main thread already -- you're not actually doing the work in the signal handler are you?
So you have two tactics: use the standard self-pipe trick to turn the signal into an event on an fd, the "normal" way to handle things like SIGTERM, SIGINT and so on. You call socketpair or pipe to make a pipe, then write a byte into the pipe from the signal handler. You read the byte back from you select loop. You commonly write the value of the signal as the data, but you could write anything really.
The other tactic (much more sane) is to avoid the mess with signals and setitimer completely. setitimer is seriously legacy and causes problems for all sorts of things (eg. it can cause functions like getaddrinfo to hang, a bug that still hasn't been fixed in glibc (http://www.cygwin.org/frysk/bugzilla/show_bug.cgi?id=15819). Signals are bad for your health. So the "normal" tactic is to use the timeout argument to select. You have a linked list of timers, objects you use to manager periodic events in your code. When you call select, you use as the timeout the shortest of your remaining timers. When the select call returns, you check if any timers are expired and call the timer handler as well as the handlers for your fd events. That's a standard application event loop. This way your loop code so you can listen for timer-driven events as well as fd-driven events. Pretty much every application on your system uses some variant on this mechanism.
Is an option for you doing something like this?
While(1) {
int rc = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
if ((rc < 0) && (errno == EINTR) )
continue;
else {
// some instructions
}
}
If this is not an option for you you can probably use pselect which adds a parameter to the end (sigmask) which specifies a set of signals that should be blocked during the pselect(), see here

Trying to exit from a blocking UDP socket read

This is a question similar to Proper way to close a blocking UDP socket. I have a thread in C which is reading from a UDP socket. The read is blocking. I would like to know if it is possible to be able to exit the thread, without relying on the recv() returning? For example can I close the socket from another thread and safely expect the socket read thread to exit? Didn't see any high voted answer on that thread, thats why I am asking it again.
This really depends on what system you're running under. For example, if you're running under a POSIX-compliant system and your thread is cancelable, the recv() call will be interrupted when you cancel the thread since it's a cancel point.
If you're using an older socket implementation, you could set a signal handler for your thread for something like SIGUSR1 and hope nobody else wanted it and signal, since recv() will interrupt on a signal. Your best option is not to block, if at all possible.
I don't think closing a socket involved in a blocking operation is a safe guaranteed way of terminating the operation. For instance, kernel.org warns darkly:
It is probably unwise to close file descriptors while they may be in
use by system calls in other threads in the same process. Since a
file descriptor may be reused, there are some obscure race conditions
that may cause unintended side effects.
Instead you could use a signal and make recv fail with EINTR
(make sure SA_RESTART is not enabled). You can send a signal to a
specific thread with pthread_kill
You could enable SO_RCVTIMEO on the socket before starting the recv
call
Personally I usually try to stay clear of all the signal nastiness but it's a viable option.
You've got a couple of options for that. A signal will interrupt the read operation, so all you need to do is make sure a signal goes off. The recv operation should fail with error number EINTR.
The simplest option is to set up a timer to interrupt your own process after some timeout e.g. 30 seconds:
itimerval timer
timeval time;
time.tv_sec = 30;
time.tv_usec = 0;
timer.it_value = time;
if( setitimer( ITIMER_REAL, &timer, NULL ) != 0 )
printf( "failed to start timer\n" );
You'll get a SIGALRM after the specified time, which will interrupt your blocking operation, and give you the chance to repeat the operation or quit.
You cannot deallocate a shared resource while another thread is or might be using it. In practice, you will find that you cannot even write code to do what you suggest.
Think about it. When you go to call close, how can you possibly know that the other thread is actually blocked in recv? What if it's about to call recv, but then another thread calls socket and gets the descriptor you just closed? Now, not only will that thread not detect any error, but it will be calling recv on the wrong socket!
There is probably a good way to solve your outer problem, the reason you need to exit from a blocking UDP socket read. There are also several ugly hacks available. The basic approach is to make the socket non-blocking and instead of making a blocking UDP socket read, fake a blocking read with select or poll. You can then abort this loop several ways:
One way is to have select time out and check an 'abort' flag when select returns.
Another way is to also select on the read end of a pipe. Send a single byte to the pipe to abort the select.
If posix complient system, you can try to monitor your thread:
pthread_create with a function that makes your recv and pthread_cond_signal just after, then returns.
The calling thread makes a pthread_cond_timedwait with the desired timeout and terminates the called thread if timed_out.

Triggering Signal Handler For I/O

Using C on Linux, how would I go about triggering a signal handler every time I write data to a buffer using the write() function. The handler will be reading all data written to the buffer at the time of execution.
Sockets support this by enabling async mode on the socket file descriptor. On Linux this is done using fcntl calls:
/* set socket owner (the process that will receive signals) */
fcntl(fd, F_SETOWN, getpid());
/* optional if you want to receive a real-time signal instead of SIGIO */
fnctl(fd, F_SETSIG, signum);
/* turn on async mode -- this is the important part which enables signal delivery */
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_ASYNC);
Use pipe() with O_ASYNC and you'll recieve a SIGIO on the read end of the pipe whenever there's new data on the pipe.
I don't 100% understand what you are trying to do, BUT
select might be what you need. waiting for data to be written to a file/pipe. You can use it to do/simulate asynchronous I/O.
If the file descriptor being used with write() is not for a FIFO, pipe (as suggested by Ken Bloom), asynchronous socket (as suggested by mark4o), and does not otherwise cause a signal (i.e. SIGIO), I suppose you could use raise() to send a signal to the current process after writing data to the buffer. Depending on what you are actually trying to achieve, this may not be the best solution.
Update
If I understand you correctly, you want to write to a file, have a SIGIO signal generated on completion of the write, and then read the data back from within the signal handler. It seems you want to use asynchronous I/O for a file.
In Asynchronous I/O on linux or: Welcome to hell, the author describes various asynchronous I/O techniques on Linux, including using the SIGIO signal. The SIGIO signal technique cannot be used with regular files.
Even though the author of the previously mentioned article doesn't think highly of the POSIX AIO API provided in the 2.6 kernel, you may want to look into it anyway as it can be used to provide notification of asychronous read/write completion to a regular file through signals and function callbacks.
In Boost application performance using asynchronous I/O, the author provides an overview of basic Linux I/O models before introducing the AIO API.

Signal safe use of sem_wait()/sem_post()

I am trying to create a wrapper on Linux which controls how many concurrent executions of something are allowed at once. To do so, I am using a system wide counting semaphore. I create the semaphore, do a sem_wait(), launch the child process and then do a sem_post() when the child terminates. That is fine.
The problem is how to safely handle signals sent to this wrapper. If it doesn't catch signals, the command might terminate without doing a sem_post(), causing the semaphore count to permanently decrease by one. So, I created a signal handler which does the sem_post(). But still, there is a problem.
If the handler is attached before the sem_wait() is performed, a signal could arrive before the sem_wait() completes, causing a sem_post() to occur without a sem_wait(). The reverse is possible if I do the sem_wait() before setting up the signal handler.
The obvious next step was to block signals during the setup of the handler and the sem_wait(). This is pseudocode of what I have now:
void handler(int sig)
{
sem_post(sem);
exit(1);
}
...
sigprocmask(...); /* Block signals */
sigaction(...); /* Set signal handler */
sem_wait(sem);
sigprocmask(...); /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);
The problem now is that the sem_wait() can block and during that time, signals are blocked. A user attempting to kill the process may end up resorting to "kill -9" which is behaviour I don't want to encourage since I cannot handle that case no matter what. I could use sem_trywait() for a small time and test sigpending() but that impacts fairness because there is no longer a guarantee that the process waiting on the semaphore the longest will get to run next.
Is there a truly safe solution here which allows me to handle signals during semaphore acquisition? I am considering resorting to a "Do I have the semaphore" global and removing the signal blocking but that is not 100% safe since acquiring the semaphore and setting the global isn't atomic but might be better than blocking signals while waiting.
Are you sure sem_wait() causes signals to be blocked? I don't think this is the case. The man page for sem_wait() says that the EINTR error code is returned from sem_wait() if it is interrupted by a signal.
You should be able to handle this error code and then your signals will be received. Have you run into a case where signals have not been received?
I would make sure you handle the error codes that sem_wait() can return. Although it may be rare, if you want to be 100% sure you want to cover 100% of your bases.
Are you sure you are approaching the problem correctly? If you want to wait for a child terminating, you may want to use the waitpid() system call. As you observed, it is not reliable to expect the child to do the sem_post() if it may receive signals.
I know this is old, but for the benefit of those still reading this courtesy of Google...
The simplest (and only?) robust solution to this problem is to use a System V semaphore, which allows the client to acquire the semaphore resource in a way which is automatically returned by the kernel NO MATTER HOW THE PROCESS EXITS.

Resources