On Fri, 2005-04-01 at 20:19 +0200, Paul J Stevens wrote: > Geo Carncross wrote: > > On Thu, 2005-03-31 at 18:45 +0200, Paul J Stevens wrote: > > > >>Geo Carncross wrote: > >> > >>>Be careful doing non-atomic things during signals. Since the signal will > >>>likely have to write to a fifo anyway, it may be better to simply select > >>>() on that fifo in the first-place... > >> > >>SELECT mtime FROM dbmail_mailboxes WHERE mailbox_idnr='%llu'; > >> > >>seems pretty atomic to me. No need for fifos at all. > > > > > > Not during a signal handler. > > http://mirbsd.bsdadvocacy.org/cman/man2/sigaction.htm > > > > The following functions are either reentrant or not interruptible by > > signals and are async-signal safe. Therefore applications may invoke > > them, without restriction, from signal-catching functions: > > > > Base Interfaces: > > > > _exit(), access(), alarm(), cfgetispeed(), cfgetospeed(), > > cfsetispeed(), > > cfsetospeed(), chdir(), chmod(), chown(), close(), creat(), dup(), > > dup2(), execle(), execve(), fcntl(), fork(), fpathconf(), fstat(), > > fsync(), getegid(), geteuid(), getgid(), getgroups(), getpgrp(), get- > > pid(), getppid(), getuid(), kill(), link(), lseek(), mkdir(), mkfifo(), > > open(), pathconf(), pause(), pipe(), raise(), read(), rename(), > > rmdir(), > > setgid(), setpgid(), setsid(), setuid(), sigaction(), sigaddset(), sig- > > delset(), sigemptyset(), sigfillset(), sigismember(), signal(), > > sigpend- > > ing(), sigprocmask(), sigsuspend(), sleep(), stat(), sysconf(), > > tcdrain(), tcflow(), tcflush(), tcgetattr(), tcgetpgrp(), > > tcsendbreak(), > > tcsetattr(), tcsetpgrp(), time(), times(), umask(), uname(), unlink(), > > utime(), wait(), waitpid(), write(). > > > > Realtime Interfaces: > > > > aio_error(), clock_gettime(), sigpause(), timer_getoverrun(), > > aio_return(), fdatasync(), sigqueue(), timer_gettime(), aio_suspend(), > > sem_post(), sigset(), timer_settime(). > > > > Unless we can be certain that the db backend won't do ANY SYSTEM CALL > > except these, we need to wait until the signal handler is done. I know > > for one, SQLite would need to use calls not here (notably: flock() and > > mmap()) > > So what if? What is our worst case scenario here? Segfaults, corrupt database > tables on sqlite, off by one errors in our 'unsollicited responses', > generally > unpredictable behaviour, stack corruption?
Add denial-of-service attacks to that list. > Or is this about being Thread-Safe[tm], which we aint anyways :-\ It's not. Thread-safety is a big joke that nobody is in on. What we mean by reentrant here is that the kernel calls themselves are reentrant. It means we can safely write to a pipe if the signal handler went off on a select() that is blocking on that pipe. Google "self pipe trick" (I'm so feeling lucky) > That said, I will take to heart your point about atomic signal handlers. > There's > one section of the code in particular that has been bothering me; the zombies > in > caused by the process-pool code (pool.c). There, I use sigalarm to trigger > the > up/down scaling of idle processes which uses fnctl based locking. So I think > it's clean, but I not so sure anymore. Must investigate. Self-pipe trick is the best way I know of to handle child processes when using select() -- Internet Connection High Quality Web Hosting http://www.internetconnection.net/
