void mainline(void) { in_critical_section = 1; do_normal_work(); while (count1 != count2) { do_signal_work(); count2++; } in_critical_section = 0; while (count1 != count2) { /* here we have to block signals, but we expect it almost never to * happen. it will only happen if a signal arrives between the * end of the first while loop and the unsetting of the * in_critical_section flag, which should be so rare that the * performance hit will be tiny */ block_signals(); do_signal_work(); count2++; unblock_signals(); } }
static void gdaui_entry_wrapper_set_value (GdauiDataEntry *iface, const GValue *value) { GdauiEntryWrapper *wrapper; g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface)); wrapper = (GdauiEntryWrapper*) iface; check_correct_init (wrapper); block_signals (wrapper); if (value) { g_return_if_fail ((G_VALUE_TYPE ((GValue *) value) == wrapper->priv->type) || (G_VALUE_TYPE ((GValue *) value) == GDA_TYPE_NULL)); (*wrapper->priv->real_class->real_set_value) (wrapper, value); if (G_VALUE_TYPE ((GValue *) value) == GDA_TYPE_NULL) wrapper->priv->null_forced = TRUE; else wrapper->priv->null_forced = FALSE; } else { (*wrapper->priv->real_class->real_set_value) (wrapper, NULL); wrapper->priv->null_forced = TRUE; } unblock_signals (wrapper); wrapper->priv->default_forced = FALSE; wrapper->priv->contents_has_changed = FALSE; gdaui_entry_wrapper_emit_signal (wrapper); }
void sig_handler_common_tt(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct tt_regs save_regs, *r; struct signal_info *info; int save_errno = errno, is_user; unprotect_kernel_mem(); r = &TASK_REGS(get_current())->tt; save_regs = *r; is_user = user_context(SC_SP(sc)); r->sc = sc; if(sig != SIGUSR2) r->syscall = -1; change_sig(SIGUSR1, 1); info = &sig_info[sig]; if(!info->is_irq) unblock_signals(); (*info->handler)(sig, (union uml_pt_regs *) r); if(is_user){ interrupt_end(); block_signals(); change_sig(SIGUSR1, 0); set_user_mode(NULL); } *r = save_regs; errno = save_errno; if(is_user) protect_kernel_mem(); }
static gboolean gb_color_picker_document_monitor_queue_oper_cb (gpointer data) { QueuedColorize *qc = data; g_assert (qc != NULL); g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (qc->self)); g_assert (GTK_IS_TEXT_MARK (qc->begin)); g_assert (GTK_IS_TEXT_MARK (qc->end)); g_assert (GTK_TEXT_BUFFER (qc->buffer)); block_signals (qc->self, IDE_BUFFER (qc->buffer)); if (qc->buffer != NULL) { GtkTextIter begin; GtkTextIter end; gtk_text_buffer_get_iter_at_mark (qc->buffer, &begin, qc->begin); gtk_text_buffer_get_iter_at_mark (qc->buffer, &end, qc->end); if (qc->uncolorize) gb_color_picker_document_monitor_uncolorize (qc->self, qc->buffer, &begin, &end); else gb_color_picker_document_monitor_colorize (qc->self, qc->buffer, &begin, &end); gtk_text_buffer_delete_mark (qc->buffer, qc->begin); gtk_text_buffer_delete_mark (qc->buffer, qc->end); } unblock_signals (qc->self, IDE_BUFFER (qc->buffer)); return G_SOURCE_REMOVE; }
static void gdaui_entry_wrapper_set_value_default (GdauiDataEntry *iface, const GValue *value) { GdauiEntryWrapper *wrapper; g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface)); wrapper = (GdauiEntryWrapper*) iface; if (wrapper->priv->value_default) gda_value_free (wrapper->priv->value_default); if (value) wrapper->priv->value_default = gda_value_copy ((GValue *) value); else wrapper->priv->value_default = gda_value_new_null (); if (wrapper->priv->default_forced) { if (G_VALUE_TYPE (wrapper->priv->value_default) == wrapper->priv->type) { check_correct_init (wrapper); block_signals (wrapper); gdaui_entry_wrapper_set_value (iface, wrapper->priv->value_default); unblock_signals (wrapper); wrapper->priv->default_forced = TRUE; } else { check_correct_init (wrapper); (*wrapper->priv->real_class->real_set_value) (wrapper, NULL); } gdaui_entry_wrapper_emit_signal (wrapper); } }
static void update_visibility(adapter_data *adapter) { gboolean inconsistent, enabled; block_signals(adapter); /* Switch off a few widgets */ gtk_widget_set_sensitive (adapter->button_discoverable, adapter->powered); gtk_widget_set_sensitive (adapter->devices_table, adapter->powered); gtk_widget_set_sensitive (adapter->name_vbox, adapter->powered); if (adapter->discoverable != FALSE && adapter->timeout_value == 0) { inconsistent = FALSE; enabled = TRUE; } else if (adapter->discoverable == FALSE) { inconsistent = enabled = FALSE; } else { inconsistent = enabled = TRUE; } gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (adapter->button_discoverable), inconsistent); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (adapter->button_discoverable), enabled); unblock_signals(adapter); }
static void record_signal_delivery (int signo) { block_signals (); (*signal_history_pointer++) = signo; if (signal_history_pointer >= (& (signal_history [sizeof (signal_history)]))) signal_history_pointer = (&signal_history[0]); unblock_signals (); }
static void real_alarm_handler(struct sigcontext *sc) { struct uml_pt_regs regs; if (sc != NULL) copy_sc(®s, sc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); }
static void real_alarm_handler(mcontext_t *mc) { struct uml_pt_regs regs; if (mc != NULL) get_regs_from_mc(®s, mc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); }
/* Execute a compiler backend, capturing all output to the given paths the full * path to the compiler to run is in argv[0]. */ int execute(char **argv, int fd_out, int fd_err, pid_t *pid) { int status; cc_log_argv("Executing ", argv); block_signals(); *pid = fork(); unblock_signals(); if (*pid == -1) { fatal("Failed to fork: %s", strerror(errno)); } if (*pid == 0) { /* Child. */ dup2(fd_out, 1); close(fd_out); dup2(fd_err, 2); close(fd_err); x_exit(execv(argv[0], argv)); } close(fd_out); close(fd_err); if (waitpid(*pid, &status, 0) != *pid) { fatal("waitpid failed: %s", strerror(errno)); } block_signals(); *pid = 0; unblock_signals(); if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) { return -1; } return WEXITSTATUS(status); }
/* \param xdf pointer of a valid xdf file with mode XDF_WRITE * * Write the header of the file format */ static int init_file_content(struct xdf* xdf) { int retval = 0; sigset_t oldmask; block_signals(&oldmask); if (xdf->ops->write_header(xdf) || fsync(xdf->fd)) retval = -1; unblock_signals(&oldmask); return retval; }
/* \param xdf pointer to a valid xdffile with mode XDF_WRITE * * Finish the file */ static int complete_file_content(struct xdf* xdf) { int retval = 0; sigset_t oldmask; block_signals(&oldmask); if (xdf->ops->complete_file(xdf) || fsync(xdf->fd)) retval = -1; unblock_signals(&oldmask); return retval; }
void user_signal(int sig, union uml_pt_regs *regs) { struct signal_info *info; regs->skas.is_user = 1; regs->skas.fault_addr = 0; regs->skas.fault_type = 0; regs->skas.trap_type = 0; info = &sig_info[sig]; (*info->handler)(sig, regs); unblock_signals(); }
static void gdaui_entry_wrapper_set_ref_value (GdauiDataEntry *iface, const GValue *value) { GdauiEntryWrapper *wrapper; gboolean changed = TRUE; GValue *evalue; g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface)); wrapper = (GdauiEntryWrapper*) iface; check_correct_init (wrapper); /* compare existing value and the one provided as argument */ if (wrapper->priv->real_class->value_is_equal_to) changed = ! wrapper->priv->real_class->value_is_equal_to (wrapper, value); else { evalue = gdaui_entry_wrapper_get_value (iface); g_assert (evalue); if ((!value || (G_VALUE_TYPE (value) == GDA_TYPE_NULL)) && (G_VALUE_TYPE (evalue) == GDA_TYPE_NULL)) changed = FALSE; else if (!gda_value_differ ((GValue *) value, evalue)) changed = FALSE; gda_value_free (evalue); } /* get rid on any existing orig value */ if (wrapper->priv->value_ref) { gda_value_free (wrapper->priv->value_ref); wrapper->priv->value_ref = NULL; } /* apply changes, if any */ if (changed) { block_signals (wrapper); gdaui_entry_wrapper_set_value (iface, value); unblock_signals (wrapper); } if (value) { g_return_if_fail ((G_VALUE_TYPE ((GValue *) value) == wrapper->priv->type) || (G_VALUE_TYPE ((GValue *) value) == GDA_TYPE_NULL)); wrapper->priv->value_ref = gda_value_copy ((GValue *) value); } else wrapper->priv->value_ref = gda_value_new_null (); /* signal changes if any */ if (changed) gdaui_entry_wrapper_emit_signal (wrapper); }
static void remove_job(LstNode ln, int status) { Job *job; job = (Job *)Lst_Datum(ln); Lst_Remove(&runningJobs, ln); block_signals(); free(Lst_Datum(job->p)); Lst_Remove(&job_pids, job->p); unblock_signals(); nJobs--; if (job->flags & JOB_IS_EXPENSIVE) expensive_job = false; process_job_status(job, status); }
void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct uml_pt_regs *r; void (*handler)(int, struct uml_pt_regs *); int save_user, save_errno = errno; /* * This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. * XXX Figure out why this is better than SA_NODEFER */ if (sig == SIGSEGV) { change_sig(SIGSEGV, 1); /* * For segfaults, we want the data from the * sigcontext. In this case, we don't want to mangle * the process registers, so use a static set of * registers. For other signals, the process * registers are OK. */ r = &ksig_regs[cpu()]; copy_sc(r, sc_ptr); } else r = TASK_REGS(get_current()); save_user = r->is_user; r->is_user = 0; if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || (sig == SIGILL) || (sig == SIGTRAP)) GET_FAULTINFO_FROM_SC(r->faultinfo, sc); change_sig(SIGUSR1, 1); handler = sig_info[sig]; /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */ if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) unblock_signals(); handler(sig, r); errno = save_errno; r->is_user = save_user; }
/* * sigprocmask - * return: * how(in): * set(in/out): * oldset(out): * * Note: */ int sigprocmask (int how, sigset_t * set, sigset_t * oldset) { switch (how) { case SIG_BLOCK: return (block_signals (set, oldset)); case SIG_UNBLOCK: return (unblock_signals (set, oldset)); case SIG_SETMASK: return (setmask (set, oldset)); } return (-1); }
void sig_handler_common_tt(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct tt_regs save_regs, *r; struct signal_info *info; int save_errno = errno, is_user; unprotect_kernel_mem(); /* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. */ if(sig == SIGSEGV) change_sig(SIGSEGV, 1); /* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. */ if(sig == SIGSEGV) change_sig(SIGSEGV, 1); r = &TASK_REGS(get_current())->tt; save_regs = *r; is_user = user_context(SC_SP(sc)); r->sc = sc; if(sig != SIGUSR2) r->syscall = -1; info = &sig_info[sig]; if(!info->is_irq) unblock_signals(); (*info->handler)(sig, (union uml_pt_regs *) r); if(is_user){ interrupt_end(); block_signals(); set_user_mode(NULL); } *r = save_regs; errno = save_errno; if(is_user) protect_kernel_mem(); }
void Microsoft2Grabber::start() { block_signals(); //GetCameraSettings(); /*hDepthMutex = CreateMutex(NULL,false,NULL); if(hDepthMutex == NULL) throw exception("Could not create depth mutex"); hColorMutex = CreateMutex(NULL,false,NULL); if(hColorMutex == NULL) throw exception("Could not create color mutex");*/ //hFrameEvent = (WAITABLE_HANDLE)CreateEvent(NULL,FALSE,FALSE,NULL); HRESULT hr = m_pMultiSourceFrameReader->SubscribeMultiSourceFrameArrived(&hFrameEvent); if(FAILED(hr)) { throw exception("Couldn't subscribe frame"); } hStopEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); hKinectThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)&ProcessThread, this, 0, NULL ); //boost::this_thread::sleep (boost::posix_time::seconds (1)); unblock_signals(); }
static void sig_handler_common(int sig, mcontext_t *mc) { struct uml_pt_regs r; int save_errno = errno; r.is_user = 0; if (sig == SIGSEGV) { get_regs_from_mc(&r, mc); GET_FAULTINFO_FROM_MC(r.faultinfo, mc); } if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) unblock_signals(); (*sig_info[sig])(sig, &r); errno = save_errno; }
static void sig_handler_common(int sig, struct sigcontext *sc) { struct uml_pt_regs r; int save_errno = errno; r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ copy_sc(&r, sc); GET_FAULTINFO_FROM_SC(r.faultinfo, sc); } /* enable signals if sig isn't IRQ signal */ if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM)) unblock_signals(); (*sig_info[sig])(sig, &r); errno = save_errno; }
int main(int argc, char** argv) { sigset_t set; pthread_t t; test_assert(argc == 2); num_its = atoi(argv[1]); test_assert(num_its > 0); atomic_printf("Running 2^%d iterations in two threads\n", num_its); atomic_printf("parent %d: blocking all sigs ...\n", getpid()); sigfillset(&set); test_assert(0 == pthread_sigmask(SIG_BLOCK, &set, NULL)); pthread_create(&t, NULL, thread, NULL); unblock_signals(); syscall_spam(); atomic_puts("EXIT-SUCCESS"); return 0; }
void pcl::OpenNIGrabber::start () { try { // check if we need to start/stop any stream if (image_required_ && !device_->isImageStreamRunning ()) { block_signals (); device_->startImageStream (); //startSynchronization (); } if (depth_required_ && !device_->isDepthStreamRunning ()) { block_signals (); if (device_->hasImageStream () && !device_->isDepthRegistered () && device_->isDepthRegistrationSupported ()) { device_->setDepthRegistration (true); } device_->startDepthStream (); //startSynchronization (); } if (ir_required_ && !device_->isIRStreamRunning ()) { block_signals (); device_->startIRStream (); } running_ = true; } catch (openni_wrapper::OpenNIException& ex) { PCL_THROW_EXCEPTION (pcl::IOException, "Could not start streams. Reason: " << ex.what ()); } // workaround, since the first frame is corrupted boost::this_thread::sleep (boost::posix_time::seconds (1)); unblock_signals (); }
void flush_thread_tt(void) { unsigned long stack; int new_pid; stack = alloc_stack(0, 0); if(stack == 0){ printk(KERN_ERR "flush_thread : failed to allocate temporary stack\n"); do_exit(SIGKILL); } new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp); if(new_pid < 0){ printk(KERN_ERR "flush_thread : new thread failed, errno = %d\n", -new_pid); do_exit(SIGKILL); } if(current_thread->cpu == 0) forward_interrupts(new_pid); current->thread.request.op = OP_EXEC; current->thread.request.u.exec.pid = new_pid; unprotect_stack((unsigned long) current_thread); os_usr1_process(os_getpid()); change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 0); enable_timer(); free_page(stack); protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); stack_protections((unsigned long) current_thread); force_flush_all(); unblock_signals(); }
void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct skas_regs *r; struct signal_info *info; int save_errno = errno; int save_user; r = &TASK_REGS(get_current())->skas; save_user = r->is_user; r->is_user = 0; r->fault_addr = SC_FAULT_ADDR(sc); r->fault_type = SC_FAULT_TYPE(sc); r->trap_type = SC_TRAP_TYPE(sc); change_sig(SIGUSR1, 1); info = &sig_info[sig]; if(!info->is_irq) unblock_signals(); (*info->handler)(sig, (union uml_pt_regs *) r); errno = save_errno; r->is_user = save_user; }
void gb_color_picker_document_monitor_set_color_tag_at_cursor (GbColorPickerDocumentMonitor *self, GstyleColor *color) { GtkTextMark *insert; GtkTextIter cursor; g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self)); g_return_if_fail (GSTYLE_IS_COLOR (color)); g_return_if_fail (self->buffer != NULL); insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(self->buffer)); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER(self->buffer), &cursor, insert); if (!self->is_in_user_action) { gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (self->buffer)); self->is_in_user_action = TRUE; } block_signals (self, self->buffer); gb_color_picker_helper_set_color_tag_at_iter (&cursor, color, TRUE); unblock_signals (self, self->buffer); }
static void* thread(void* unused) { unblock_signals(); syscall_spam(); return NULL; }
void spawn_filter(const char *filter_command) { int input_pipe_fds[2]; int output_pipe_fds[2]; mypipe(input_pipe_fds); filter_input_fd = input_pipe_fds[1]; /* rlwrap writes filter input to this */ mypipe(output_pipe_fds); filter_output_fd = output_pipe_fds[0]; /* rlwrap reads filter output from here */ DPRINTF1(DEBUG_FILTERING, "preparing to spawn filter <%s>", filter_command); assert(!command_pid || signal_handlers_were_installed); /* if there is a command, then signal handlers are installed */ if ((filter_pid = fork()) < 0) myerror(FATAL|USE_ERRNO, "Cannot spawn filter '%s'", filter_command); else if (filter_pid == 0) { /* child */ int signals_to_allow[] = {SIGPIPE, SIGCHLD, SIGALRM, SIGUSR1, SIGUSR2}; char **argv; unblock_signals(signals_to_allow); /* when we run a pager from a filter we want to catch these */ DEBUG_RANDOM_SLEEP; i_am_child = TRUE; /* set environment for filter (it needs to know at least the file descriptors for its input and output) */ if (!getenv("RLWRAP_FILTERDIR")) mysetenv("RLWRAP_FILTERDIR", add2strings(DATADIR,"/rlwrap/filters")); mysetenv("PATH", add3strings(getenv("RLWRAP_FILTERDIR"),":",getenv("PATH"))); mysetenv("RLWRAP_VERSION", VERSION); mysetenv("RLWRAP_COMMAND_PID", as_string(command_pid)); mysetenv("RLWRAP_COMMAND_LINE", command_line); if (impatient_prompt) mysetenv("RLWRAP_IMPATIENT", "1"); mysetenv("RLWRAP_INPUT_PIPE_FD", as_string(input_pipe_fds[0])); mysetenv("RLWRAP_OUTPUT_PIPE_FD", as_string(output_pipe_fds[1])); mysetenv("RLWRAP_MASTER_PTY_FD", as_string(master_pty_fd)); close(filter_input_fd); close(filter_output_fd); if (scan_metacharacters(filter_command, "'|\"><")) { /* if filter_command contains shell metacharacters, let the shell unglue them */ char *exec_command = add3strings("exec", " ", filter_command); argv = list4("sh", "-c", exec_command, NULL); } else { /* if not, split and feed to execvp directly (cheaper, better error message) */ argv = split_with(filter_command, " "); } assert(argv[0]); if(execvp(argv[0], argv) < 0) { char *sorry = add3strings("Cannot exec filter '", argv[0], add2strings("': ", strerror(errno))); write_message(output_pipe_fds[1], TAG_ERROR, sorry, "to stdout"); /* this will kill rlwrap */ mymicrosleep(100 * 1000); /* 100 sec for rlwrap to go away should be enough */ exit (-1); } assert(!"not reached"); } else { DEBUG_RANDOM_SLEEP; signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE - we have othere ways to deal with filter death */ DPRINTF1(DEBUG_FILTERING, "spawned filter with pid %d", filter_pid); close (input_pipe_fds[0]); close (output_pipe_fds[1]); } }
/*- *----------------------------------------------------------------------- * JobExec -- * Execute the shell for the given job. Called from JobStart * * Side Effects: * A shell is executed, outputs is altered and the Job structure added * to the job table. *----------------------------------------------------------------------- */ static void JobExec(Job *job) { pid_t cpid; /* ID of new child */ struct job_pid *p; int fds[4]; int *fdout = fds; int *fderr = fds+2; int i; banner(job, stdout); setup_engine(1); /* Create the pipe by which we'll get the shell's output. */ if (pipe(fdout) == -1) Punt("Cannot create pipe: %s", strerror(errno)); if (pipe(fderr) == -1) Punt("Cannot create pipe: %s", strerror(errno)); block_signals(); if ((cpid = fork()) == -1) { Punt("Cannot fork"); unblock_signals(); } else if (cpid == 0) { supervise_jobs = false; /* standard pipe code to route stdout and stderr */ close(fdout[0]); if (dup2(fdout[1], 1) == -1) Punt("Cannot dup2(outPipe): %s", strerror(errno)); if (fdout[1] != 1) close(fdout[1]); close(fderr[0]); if (dup2(fderr[1], 2) == -1) Punt("Cannot dup2(errPipe): %s", strerror(errno)); if (fderr[1] != 2) close(fderr[1]); /* * We want to switch the child into a different process family * so we can kill it and all its descendants in one fell swoop, * by killing its process family, but not commit suicide. */ (void)setpgid(0, getpid()); if (random_delay) if (!(nJobs == 1 && no_jobs_left())) usleep(random() % random_delay); setup_all_signals(SigHandler, SIG_DFL); unblock_signals(); /* this exits directly */ run_gnode_parallel(job->node); /*NOTREACHED*/ } else { supervise_jobs = true; job->pid = cpid; /* we set the current position in the buffers to the beginning * and mark another stream to watch in the outputs mask */ for (i = 0; i < 2; i++) prepare_pipe(&job->in[i], fds+2*i); } /* * Now the job is actually running, add it to the table. */ nJobs++; Lst_AtEnd(&runningJobs, job); if (job->flags & JOB_IS_EXPENSIVE) expensive_job = true; p = emalloc(sizeof(struct job_pid)); p->pid = cpid; Lst_AtEnd(&job_pids, p); job->p = Lst_Last(&job_pids); unblock_signals(); if (DEBUG(JOB)) { LstNode ln; (void)fprintf(stdout, "Running %ld (%s)\n", (long)cpid, job->node->name); for (ln = Lst_First(&job->node->commands); ln != NULL ; ln = Lst_Adv(ln)) fprintf(stdout, "\t%s\n", (char *)Lst_Datum(ln)); (void)fflush(stdout); } }
/* * returns the reschedule delay * negative means *stop* */ int waiteventloop (struct event_thread *waiter) { sigset_t set; int event_nr; int r; if (!waiter->event_nr) waiter->event_nr = dm_geteventnr(waiter->mapname); if (!(waiter->dmt = dm_task_create(DM_DEVICE_WAITEVENT))) { condlog(0, "%s: devmap event #%i dm_task_create error", waiter->mapname, waiter->event_nr); return 1; } if (!dm_task_set_name(waiter->dmt, waiter->mapname)) { condlog(0, "%s: devmap event #%i dm_task_set_name error", waiter->mapname, waiter->event_nr); dm_task_destroy(waiter->dmt); return 1; } if (waiter->event_nr && !dm_task_set_event_nr(waiter->dmt, waiter->event_nr)) { condlog(0, "%s: devmap event #%i dm_task_set_event_nr error", waiter->mapname, waiter->event_nr); dm_task_destroy(waiter->dmt); return 1; } dm_task_no_open_count(waiter->dmt); /* accept wait interruption */ set = unblock_signals(); /* wait */ r = dm_task_run(waiter->dmt); /* wait is over : event or interrupt */ pthread_sigmask(SIG_SETMASK, &set, NULL); if (!r) /* wait interrupted by signal */ return -1; dm_task_destroy(waiter->dmt); waiter->dmt = NULL; waiter->event_nr++; /* * upon event ... */ while (1) { condlog(3, "%s: devmap event #%i", waiter->mapname, waiter->event_nr); /* * event might be : * * 1) a table reload, which means our mpp structure is * obsolete : refresh it through update_multipath() * 2) a path failed by DM : mark as such through * update_multipath() * 3) map has gone away : stop the thread. * 4) a path reinstate : nothing to do * 5) a switch group : nothing to do */ pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock); lock(waiter->vecs->lock); r = update_multipath(waiter->vecs, waiter->mapname); lock_cleanup_pop(waiter->vecs->lock); if (r) { condlog(2, "%s: event checker exit", waiter->mapname); return -1; /* stop the thread */ } event_nr = dm_geteventnr(waiter->mapname); if (waiter->event_nr == event_nr) return 1; /* upon problem reschedule 1s later */ waiter->event_nr = event_nr; } return -1; /* never reach there */ }