| To: | Loic Domaigne <yyyyyyyy@xxxxxxx> |
|---|---|
| Subject: | Re: Defect in XSH pthread_sigmask (revised 1) |
| From: | Dave Butenhof <yyyyyyyyyyyyyy@xxxxxx> |
| Date: | Thu, 24 Jul 2003 14:52:06 -0400 |
| Cc: | yyyyyyyyyyyyyyy@xxxxxxxxxxxxx |
| Organization: | Hewlett-Packard Company |
| References: | <28723.1058275008@www62.gmx.net> <1332.1058291547@www33.gmx.net> |
|
Loic, First, thanks for the effort in trying to write example code. This is a great contribution, in an area that's been sadly overlooked. Please don't take any of this as a complaint about what you did! At the teleconference today, we discussed ERN 114, which is your lengthy example for the use of pthread_sigmask() and sigwait(). I could make some minor stylistic comments (for example, that the thread start routine really should have the standard prototype 'void *name (void*)' rather than 'void name(void)'). But we talked about the separate issues of size and complexity. There would be value in having large and fully worked examples that tie together various aspects of the standard. However, those would be best represented somewhere outside the document; where someone can download them and use them, rather than having to try to cut and paste from a pdf or html document, or even worse re-type from a printed document. We didn't try to work out how that would be done. Examples in the main body of the standard should be small and concise, so they can easily be read and absorbed. They should present one or two concepts in less than a page of text so that it can be seen at the same time as the context it explains. I've stripped your unfortunate program "to the bones", though as always there's plenty of room for discussion about what constitutes "bone". For example, your universal check for errors is academically laudable, but does increase the size. I've substituted a simple comment in most places. I removed error checking entirely for sigemptyset() and sigaddset() because when using standard signal number macros there should be no excuse for any implementation reporting an error; and it saves space. There's no need to show the header files, because they're well defined by the standard... and again, it saves space. I've removed your nicely generalized signal mask and 'die' routines, again in the name of conserving space. There's no need, in the first place, for a generalized routine to manage signal masks here. You use the routine twice, and it's redundant because both calls construct the same mask. Instead, I've used the sig*() functions directly, once, on a static mask. We'd actually agreed to remove the main() wrapper and show the sigmask and thread create code "disembodied". But as I sat down to do it I realized that's shaving the bones themselves rather thin. In this case is IS relevant that the pthread_sigmask() be done "at the top of" main() in order to ensure that the mask is inherited by all threads. Else the sigwait() protocol would be unreliable. So, for the purpose of comment and discussion, here's the "stripped" version: static sigset_t signal_mask; /* signals to block */ int main (int argc, char *argv[]) { pthread_t sig_thr_id; /* signal handler thread ID */ int rc; /* return code */ sigemptyset (&signal_mask); sigaddset (&signal_mask, SIGINT); sigaddset (&signal_mask, SIGTERM); sigaddset (&signal_mask, SIGQUIT); rc = pthread_sigmask (SIG_BLOCK, &signal_mask, NULL); if (rc != 0) { /* handle error */ } rc = pthread_create (&sig_thr_id, NULL, signal_thread, NULL); if (rc != 0) { /* handle error */ } /* APPLICATION CODE */ return 0; } void *signal_thread (void *arg) { int sig_caught; /* signal caught */ int rc; /* returned code */ rc = sigwait (&signal_mask, &sig_caught); if (rc != 0) { /* handle error */ } switch (sig_caught) { case SIGINT: /* process SIGINT */ ... break; case SIGQUIT: /* process SIGQUIT */ ... break; case SIGTERM: /* process SIGTERM */ ... break; default: /* should normally not happen */ fprintf (stderr, "\nUnexpected signal %d\n", sig_caught); break; } } I think that your die() routine would make a good example of the use of strerror_r(); and when compressed somewhat vertically it's not very large. Similarly, create_sigmask() could be used as an example of the sig*set() functions. -- /--------------------[ yyyyyyyyyyyyyy@xxxxxx ]--------------------\ | Hewlett-Packard Company Tru64 UNIX & VMS Thread Architect | | My book: http://www.awl.com/cseng/titles/0-201-63392-2/ | \----[ http://homepage.mac.com/dbutenhof/Threads/Threads.html ]---/ |
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| ||
| Previous by Date: | Re: Defect in XSH errno, Andries.Brouwer |
|---|---|
| Next by Date: | Bug in TC2-d2 killpg(), mtk-lists |
| Previous by Thread: | Re: Defect in XSH pthread_sigmask (revised 1), Loic Domaigne |
| Next by Thread: | Re: Defect in XSH pthread_sigmask (revised 1), Loic Domaigne |
| Indexes: | [Date] [Thread] [All Lists] |