diff options
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c | 53 | ||||
| -rw-r--r-- | usr/src/lib/fm/libldom/sparc/ldom_utils.c | 66 | ||||
| -rw-r--r-- | usr/src/lib/fm/libldom/sparc/ldom_utils.h | 5 | ||||
| -rw-r--r-- | usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c | 37 |
4 files changed, 75 insertions, 86 deletions
diff --git a/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c b/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c index 9367cc0221..be9e78cc3e 100644 --- a/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c +++ b/usr/src/lib/fm/libldom/sparc/ldmsvcs_utils.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <stdlib.h> @@ -104,7 +103,7 @@ static struct poller_s { pthread_mutex_t mt; pthread_cond_t cv; pthread_t polling_tid; - int polling_thr_sig; + int notify_pipe[2]; int doreset; int doexit; int nclients; @@ -115,7 +114,7 @@ static struct poller_s { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, - SIGTERM, + {-1, -1}, 1, 0, 0, @@ -190,7 +189,7 @@ read_stream(int fd, void *buf, size_t size) */ do { if ((rv = read(fd, (void *)currentp, data_left)) < 0) { - if (errno == EAGAIN && poll(&pollfd, 1, -1) > 0) + if (errno == EAGAIN && poll(&pollfd, 1, 3000) > 0) continue; /* retry */ else return (1); @@ -427,9 +426,11 @@ poller_shutdown(boolean_t wait) (void) pthread_mutex_unlock(&pollbase.mt); if (wait == B_TRUE) { - /* stop the poller thread and wait for it to end */ - (void) pthread_kill(pollbase.polling_tid, - pollbase.polling_thr_sig); + /* + * Write a byte to the pipe to notify the poller thread to exit. + * Then wait for it to exit. + */ + (void) write(pollbase.notify_pipe[0], "1", 1); (void) pthread_join(pollbase.polling_tid, NULL); } } @@ -444,7 +445,9 @@ static void * poller_loop(void *arg) { struct ldmsvcs_info *lsp; - pollfd_t pollfd; + pollfd_t pollfd[2]; + struct pollfd *pipe_fd = &pollfd[0]; + struct pollfd *recv_fd = &pollfd[1]; int ier; lsp = (struct ldmsvcs_info *)arg; @@ -470,6 +473,7 @@ poller_loop(void *arg) pollbase.doreset = 0; } + (void) pthread_mutex_unlock(&pollbase.mt); if ((ier = channel_openreset(lsp)) == 1) { @@ -482,18 +486,28 @@ poller_loop(void *arg) continue; } - pollfd.events = POLLIN; - pollfd.revents = 0; - pollfd.fd = lsp->fds_chan.fd; + pipe_fd->fd = pollbase.notify_pipe[1]; /* notification pipe */ + pipe_fd->events = POLLIN; + pipe_fd->revents = 0; + recv_fd->fd = lsp->fds_chan.fd; /* FMA LDC */ + recv_fd->events = POLLIN; + recv_fd->revents = 0; - if (poll(&pollfd, 1, -1) <= 0 || read_msg(lsp) != 0) { - /* - * read error and/or fd got closed - */ + if (poll(pollfd, 2, -1) <= 0) { + /* fd got closed */ + (void) pthread_mutex_lock(&pollbase.mt); + pollbase.doreset = 1; + (void) pthread_mutex_unlock(&pollbase.mt); + channel_close(lsp); + } else if (pipe_fd->revents & POLLIN) { + /* Receive a notification to exit */ + channel_close(lsp); + pthread_exit((void *)NULL); + } else if (read_msg(lsp) != 0) { + /* fail to read a message from the LDOM manager */ (void) pthread_mutex_lock(&pollbase.mt); pollbase.doreset = 1; (void) pthread_mutex_unlock(&pollbase.mt); - channel_close(lsp); } } @@ -517,10 +531,9 @@ poller_init(struct ldmsvcs_info *lsp) /* * create a joinable polling thread for receiving messages - * The polling_thr_sig stores the signal number that is not - * currently masked. it is used to stop the poller thread. + * The notify pipe is for stopping the thread */ - pollbase.polling_thr_sig = ldom_find_thr_sig(); + (void) notify_setup(pollbase.notify_pipe); if (pthread_create(&pollbase.polling_tid, attr, poller_loop, lsp) != 0) rc = 1; diff --git a/usr/src/lib/fm/libldom/sparc/ldom_utils.c b/usr/src/lib/fm/libldom/sparc/ldom_utils.c index 2fe3961bd9..1bb7482c76 100644 --- a/usr/src/lib/fm/libldom/sparc/ldom_utils.c +++ b/usr/src/lib/fm/libldom/sparc/ldom_utils.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -31,60 +30,17 @@ */ #include <stdio.h> -#include <signal.h> -#include <pthread.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> -/* - * ldom_find_thr_sig() - * Description: - * Find an unmasked signal which is used for terminating the thread - * - * If the libldom.so thread is started before all fmd modules are loaded, - * all signals are unmasked. Either SIGTERM or SIGUSR1 can be used to - * stop the thread. - * If the thread is started by a fmd module, fmd has masked all signals - * except the client.thrsig and a list of reserver/non-catchable signals. - * The fmd client.thrsig signal must be used to stop the thread. The default - * value of the client.thrsig is SIGUSR1. - * - * This fucntion first tries to check if the SIGTERM, SIGUSR1 or SIGUSR2 - * signal is umasked. If so, select this signal. - * Otherwise, go through all the signals and find an umasked one. - */ -int -ldom_find_thr_sig(void) +boolean_t +notify_setup(int *notify_pipe) { - int i; - sigset_t oset, rset; - int sig[] = {SIGTERM, SIGUSR1, SIGUSR2}; - int sig_sz = sizeof (sig) / sizeof (int); - int rc = SIGTERM; - - /* prefered set of signals that are likely used to terminate threads */ - (void) sigemptyset(&oset); - (void) pthread_sigmask(SIG_SETMASK, NULL, &oset); - for (i = 0; i < sig_sz; i++) { - if (sigismember(&oset, sig[i]) == 0) { - return (sig[i]); - } + if (pipe(notify_pipe) < 0) { + return (B_FALSE); + } else { + fcntl(notify_pipe[1], F_SETFL, O_NONBLOCK); } - - /* reserved set of signals that are not allowed to terminate thread */ - (void) sigemptyset(&rset); - (void) sigaddset(&rset, SIGABRT); - (void) sigaddset(&rset, SIGKILL); - (void) sigaddset(&rset, SIGSTOP); - (void) sigaddset(&rset, SIGCANCEL); - - /* Find signal that is not masked and not in the reserved list. */ - for (i = 1; i < MAXSIG; i++) { - if (sigismember(&rset, i) == 1) { - continue; - } - if (sigismember(&oset, i) == 0) { - return (i); - } - } - - return (rc); + return (B_TRUE); } diff --git a/usr/src/lib/fm/libldom/sparc/ldom_utils.h b/usr/src/lib/fm/libldom/sparc/ldom_utils.h index 3475120e9e..995a956213 100644 --- a/usr/src/lib/fm/libldom/sparc/ldom_utils.h +++ b/usr/src/lib/fm/libldom/sparc/ldom_utils.h @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -35,7 +34,7 @@ extern "C" { #endif -extern int ldom_find_thr_sig(void); +extern boolean_t notify_setup(int *); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c b/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c index fdf15cf489..f183b5b7f9 100644 --- a/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c +++ b/usr/src/lib/fm/libldom/sparc/ldom_xmpp_client.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -81,7 +80,7 @@ static void handle_ldm_resp(xmpp_conn_t *conn, char *buf, size_t buf_size); static void handle_ldm_event(xmpp_conn_t *conn, char *buf, size_t buf_size); static int xmpp_enable = 0; -static int xmpp_thr_sig = SIGTERM; +static int xmpp_notify_pipe[2]; static pthread_t xmpp_tid = 0; static pthread_mutex_t xmpp_tid_lock = PTHREAD_MUTEX_INITIALIZER; @@ -344,6 +343,9 @@ xmpp_client_thr(void *data) int cnt; char buf[XMPP_BUF_SIZE]; xmpp_conn_t conn; + pollfd_t pollfd[2]; + struct pollfd *pipe_fd = &pollfd[0]; + struct pollfd *recv_fd = &pollfd[1]; while (xmpp_enable) { /* clear the conn struct */ @@ -364,10 +366,26 @@ xmpp_client_thr(void *data) continue; } + pipe_fd->fd = xmpp_notify_pipe[1]; /* notification pipe */ + pipe_fd->events = POLLIN; + recv_fd->fd = conn.fd; /* XMPP connection */ + recv_fd->events = POLLIN; + /* process input */ while ((conn.state != CONN_STATE_FAILURE) && (conn.state != CONN_STATE_DONE) && xmpp_enable) { + /* Wait for xmpp input or the notification */ + pipe_fd->revents = 0; + recv_fd->revents = 0; + if (poll(pollfd, 2, -1) <= 0) { + break; + } else if (pipe_fd->revents & POLLIN) { + /* Receive a notification to exit */ + xmpp_close(&conn); + pthread_exit((void *)NULL); + } + /* * Assume the document size of a ldmd response is * less than 1KB. This assumption is valid with the @@ -517,7 +535,11 @@ xmpp_stop(void) (void) pthread_mutex_lock(&xmpp_tid_lock); xmpp_enable = 0; if (xmpp_tid) { - (void) pthread_kill(xmpp_tid, xmpp_thr_sig); + /* + * Write a byte to the pipe to notify the xmpp thread to exit. + * Then wait for it to exit. + */ + (void) write(xmpp_notify_pipe[0], "1", 1); (void) pthread_join(xmpp_tid, NULL); xmpp_tid = 0; } @@ -550,11 +572,10 @@ xmpp_start(void) xmpp_enable = 1; /* - * create xmpp client thread for receiving domain events - * xmpp_thr_sig stores the signal number that is not currently masked. - * It is used to stop the client thread. + * create xmpp client thread for receiving domain events. + * The notification pipe is for stopping the thread. */ - xmpp_thr_sig = ldom_find_thr_sig(); + (void) notify_setup(xmpp_notify_pipe); (void) pthread_create(&xmpp_tid, NULL, xmpp_client_thr, NULL); (void) pthread_mutex_unlock(&xmpp_tid_lock); |
