Hi, all,
I wrote a small program to handle thousands of TCP connections and tens
of segments each second on each connection. To do this, I use rtsignal
to notify application when socket is ready for read. The basic idea of
this program is like this:
After program start, block the SIGRTMIN and SIGIO in the main thread by:
sigset_t sset;
sigemptyset(&sset);
sigaddset( &sset, SIGRTMIN );
sigaddset( &sset, SIGIO );
pthread_sigmask( SIG_BLOCK, &sset, NULL );
In one thread, accept the connection request and set signal on it:
...
Int fd = accept( ......);
flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK | O_ASYNC );
fcntl(sock, F_SETSIG, SIGRTMIN );
fcntl(sock, F_SETOWN, sigpid );
...
And in the work thread, use sigwaitinfo to get the rtsignal from queue.
sigset_t sset;
sigemptyset( &sset );
sigaddset( &sset, SIGIO );
sigaddset( &sset, SIGRTMIN );
while ( true ) {
int sig = sigwaitinfo( &sset, &siginfo );
if ( sig == SIGRTMIN ) {
if ( siginfo.si_band & POLL_IN ) {
do_read_pack( siginfo.si_fd );
}
else if ( siginfo.si_band & POLL_HUP ) {
do_disconn( siginfo.si_fd );
}
else if ( siginfo.si_band & POLL_ERR ) {
do_error( siginfo.si_fd );
}
}
}
This program can work on most of the platforms, but, in FC2, the work
thread is blocked on sigwaitinfo while the signal is queuing in the
kernel. (I can see the number in /proc/sys/kernel/rtsig-nr is increasing
rapidly). At last, the queue overflow, and the sigwaitinfo returns a
SIGIO.
My environments is FC2 (2.6.6-1.435smp) on an old dual P3 Xeon,
glibc-2.3.3-27. This program can work in RHEL 3.0 AS (2.4.21-9.ELsmp,
glibc-2.3.2-95.6).
Has anybody ever meet the same problem as me? Or anybody has any ideas?
Thank you in advance
- Jin