本文整理汇总了C++中sigsuspend函数的典型用法代码示例。如果您正苦于以下问题:C++ sigsuspend函数的具体用法?C++ sigsuspend怎么用?C++ sigsuspend使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了sigsuspend函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: main
int main(int argc,char *argv[])
{
char cmd[CMD_SIZE];
pid_t childPid;
sigset_t blockMask,emptyMask;
struct sigaction sa;
setbuf(stdout,NULL); /* Disable buffering of stdout */
memset(cmd,0,CMD_SIZE);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = sigHandler;
if (sigaction(SIGCHLD,&sa,NULL) == -1)
{
errExit("sigaction");
}
/* Block SIGCHLD to prevent its delivery if a child terminates
before the parent commences the sigsupsend() */
sigemptyset(&blockMask);
sigaddset(&blockMask,SIGCHLD);
if (sigprocmask(SIG_SETMASK,&blockMask,NULL) == -1)
{
errExit("sigprocmask");
}
printf("Parent PID=%ld\n",(long)getpid());
switch(childPid = fork())
{
case -1:
errExit("fork");
case 0: /* Child: immediately exits to become zombie */
printf("Child (PID=%ld) exiting\n",(long)getpid());
_exit(EXIT_SUCCESS);
default: /* Parent */
sigemptyset(&emptyMask);
if (sigsuspend(&emptyMask) == -1 && errno != EINTR)
{
errExit("sigsuspend");
}
snprintf(cmd,CMD_SIZE,"ps -c | grep %s",basename(argv[0]));
cmd[CMD_SIZE - 1] = '\0'; /* Ensure string is null-terminated */
system(cmd); /* View zombie child */
/* Now send the "sure kill" signal to the zombie */
if (kill(childPid,SIGKILL) == -1)
{
errMsg("kill");
}
sleep(10); /* Give child a chance to react to signal */
printf("After sending SIGKILL to zombie (PID=%ld):\n",(long)childPid);
system(cmd); /* View zombie child again */
exit(EXIT_SUCCESS);
}
}
示例2: coro_create
void
coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssize)
{
coro_context nctx;
# if CORO_SJLJ
stack_t ostk, nstk;
struct sigaction osa, nsa;
sigset_t nsig, osig;
# endif
if (!coro)
return;
coro_init_func = coro;
coro_init_arg = arg;
new_coro = ctx;
create_coro = &nctx;
# if CORO_SJLJ
/* we use SIGUSR2. first block it, then fiddle with it. */
sigemptyset (&nsig);
sigaddset (&nsig, SIGUSR2);
sigprocmask (SIG_BLOCK, &nsig, &osig);
nsa.sa_handler = trampoline;
sigemptyset (&nsa.sa_mask);
nsa.sa_flags = SA_ONSTACK;
if (sigaction (SIGUSR2, &nsa, &osa))
{
perror ("sigaction");
abort ();
}
/* set the new stack */
nstk.ss_sp = STACK_ADJUST_PTR (sptr, ssize); /* yes, some platforms (IRIX) get this wrong. */
nstk.ss_size = STACK_ADJUST_SIZE (sptr, ssize);
nstk.ss_flags = 0;
if (sigaltstack (&nstk, &ostk) < 0)
{
perror ("sigaltstack");
abort ();
}
trampoline_done = 0;
kill (getpid (), SIGUSR2);
sigfillset (&nsig); sigdelset (&nsig, SIGUSR2);
while (!trampoline_done)
sigsuspend (&nsig);
sigaltstack (0, &nstk);
nstk.ss_flags = SS_DISABLE;
if (sigaltstack (&nstk, 0) < 0)
perror ("sigaltstack");
sigaltstack (0, &nstk);
if (~nstk.ss_flags & SS_DISABLE)
abort ();
if (~ostk.ss_flags & SS_DISABLE)
sigaltstack (&ostk, 0);
sigaction (SIGUSR2, &osa, 0);
sigprocmask (SIG_SETMASK, &osig, 0);
# elif CORO_LOSER
coro_setjmp (ctx->env);
#if __CYGWIN__ && __i386
ctx->env[8] = (long) coro_init;
ctx->env[7] = (long) ((char *)sptr + ssize) - sizeof (long);
#elif __CYGWIN__ && __x86_64
ctx->env[7] = (long) coro_init;
ctx->env[6] = (long) ((char *)sptr + ssize) - sizeof (long);
#elif defined(__MINGW32__)
ctx->env[5] = (long) coro_init;
ctx->env[4] = (long) ((char *)sptr + ssize) - sizeof (long);
#elif defined(_M_IX86)
((_JUMP_BUFFER *)&ctx->env)->Eip = (long) coro_init;
((_JUMP_BUFFER *)&ctx->env)->Esp = (long) STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
#elif defined(_M_AMD64)
((_JUMP_BUFFER *)&ctx->env)->Rip = (__int64) coro_init;
((_JUMP_BUFFER *)&ctx->env)->Rsp = (__int64) STACK_ADJUST_PTR (sptr, ssize) - sizeof (__int64);
#elif defined(_M_IA64)
((_JUMP_BUFFER *)&ctx->env)->StIIP = (__int64) coro_init;
((_JUMP_BUFFER *)&ctx->env)->IntSp = (__int64) STACK_ADJUST_PTR (sptr, ssize) - sizeof (__int64);
#else
#error "microsoft libc or architecture not supported"
#endif
# elif CORO_LINUX
coro_setjmp (ctx->env);
#if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined (JB_PC) && defined (JB_SP)
ctx->env[0].__jmpbuf[JB_PC] = (long) coro_init;
ctx->env[0].__jmpbuf[JB_SP] = (long) STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
//.........这里部分代码省略.........
示例3: main
//.........这里部分代码省略.........
timeout.tv_sec = duration / 1000;
timeout.tv_nsec = (duration % 1000) * 1000000;
//set the data for each thread and create the threads
for (i = 0; i < num_threads; i++) {
data[i].id = i;
data[i].num_operations = 0;
data[i].total_time=0;
data[i].num_insert=0;
data[i].num_remove=0;
data[i].num_search=0;
data[i].num_add = max_key/(2 * num_threads);
if (i< ((max_key/2)%num_threads)) data[i].num_add++;
data[i].seed = rand();
data[i].barrier = &barrier;
data[i].init_lock = &init_lock;
if (pthread_create(&threads[i], &attr, test, (void *)(&data[i])) != 0) {
fprintf(stderr, "Error creating thread\n");
exit(1);
}
}
pthread_attr_destroy(&attr);
/* Catch some signals */
if (signal(SIGHUP, catcher) == SIG_ERR ||
signal(SIGINT, catcher) == SIG_ERR ||
signal(SIGTERM, catcher) == SIG_ERR) {
perror("signal");
exit(1);
}
// seeds = seed_rand();
// skey_t key;
// for (i=0;i<max_key/2;++i) {
// key = my_random(&seeds[0],&seeds[1],&seeds[2]) & max_key;
// //we make sure the insert was effective (as opposed to just updating an existing entry)
// if (bst_add(key, root, 0)!=TRUE) {
// i--;
// }
// }
// bst_print(root);
/* Start threads */
barrier_cross(&barrier);
gettimeofday(&start, NULL);
if (duration > 0) {
//sleep for the duration of the experiment
nanosleep(&timeout, NULL);
} else {
sigemptyset(&block_set);
sigsuspend(&block_set);
}
//signal the threads to stop
*running = 0;
gettimeofday(&end, NULL);
/* Wait for thread completion */
for (i = 0; i < num_threads; i++) {
if (pthread_join(threads[i], NULL) != 0) {
fprintf(stderr, "Error waiting for thread completion\n");
exit(1);
}
}
DDPRINT("threads finshed\n",NULL);
//compute the exact duration of the experiment
duration = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000);
//bst_print(root);
unsigned long operations = 0;
ticks total_ticks = 0;
long reported_total = 1; //the tree contains two initial dummy nodes, INF1 and INF2
//report some experiment statistics
for (i = 0; i < num_threads; i++) {
printf("Thread %d\n", i);
printf(" #operations : %lu\n", data[i].num_operations);
printf(" #inserts : %lu\n", data[i].num_insert);
printf(" #removes : %lu\n", data[i].num_remove);
operations += data[i].num_operations;
total_ticks += data[i].total_time;
reported_total = reported_total + data[i].num_add + data[i].num_insert - data[i].num_remove;
}
printf("Duration : %d (ms)\n", duration);
printf("#txs : %lu (%f / s)\n", operations, operations * 1000.0 / duration);
//printf("Operation latency %lu\n", total_ticks / operations);
//make sure the tree is correct
printf("Expected size: %ld Actual size: %lu\n",reported_total,bst_size(root));
free(threads);
free(data);
return 0;
}
示例4: startServer
static int
startServer(char *server[])
{
sigset_t mask, old;
const char * const *cpp;
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigprocmask(SIG_BLOCK, &mask, &old);
serverpid = fork();
switch(serverpid) {
case 0:
/* Unblock */
sigprocmask(SIG_SETMASK, &old, NULL);
/*
* don't hang on read/write to control tty
*/
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
/*
* ignore SIGUSR1 in child. The server
* will notice this and send SIGUSR1 back
* at xinit when ready to accept connections
*/
signal(SIGUSR1, SIG_IGN);
/*
* prevent server from getting sighup from vhangup()
* if client is xterm -L
*/
setpgid(0,getpid());
Execute(server);
Error("unable to run server \"%s\"", server[0]);
fprintf(stderr, "Use the -- option, or make sure that %s is in your path and\n", bindir);
fprintf(stderr, "that \"%s\" is a program or a link to the right type of server\n", server[0]);
fprintf(stderr, "for your display. Possible server names include:\n\n");
for (cpp = server_names; *cpp; cpp++)
fprintf(stderr, " %s\n", *cpp);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
break;
case -1:
break;
default:
/*
* don't nice server
*/
setpriority(PRIO_PROCESS, serverpid, -1);
errno = 0;
if(! processTimeout(0, "")) {
serverpid = -1;
break;
}
/*
* kludge to avoid race with TCP, giving server time to
* set his socket options before we try to open it,
* either use the 15 second timeout, or await SIGUSR1.
*
* If your machine is substantially slower than 15 seconds,
* you can easily adjust this value.
*/
alarm(15);
sigsuspend(&old);
alarm(0);
sigprocmask(SIG_SETMASK, &old, NULL);
if (waitforserver() == 0) {
Error("unable to connect to X server");
shutdown();
serverpid = -1;
}
break;
}
return(serverpid);
}
示例5: j_waitj
/*
* wait for job to complete or change state
*
* If jobs are compiled in then this routine expects sigchld to be blocked.
*/
static int
j_waitj(Job *j,
int flags, /* see JW_* */
const char *where)
{
int rv;
/*
* No auto-notify on the job we are waiting on.
*/
j->flags |= JF_WAITING;
if (flags & JW_ASYNCNOTIFY)
j->flags |= JF_W_ASYNCNOTIFY;
if (!Flag(FMONITOR))
flags |= JW_STOPPEDWAIT;
while ((volatile int) j->state == PRUNNING ||
((flags & JW_STOPPEDWAIT) && (volatile int) j->state == PSTOPPED)) {
sigsuspend(&sm_default);
if (fatal_trap) {
int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY);
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
runtraps(TF_FATAL);
j->flags |= oldf; /* not reached... */
}
if ((flags & JW_INTERRUPT) && (rv = trap_pending())) {
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
return -rv;
}
}
j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
if (j->flags & JF_FG) {
int status;
j->flags &= ~JF_FG;
#ifdef JOBS
if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
/*
* Save the tty's current pgrp so it can be restored
* when the job is foregrounded. This is to
* deal with things like the GNU su which does
* a fork/exec instead of an exec (the fork means
* the execed shell gets a different pid from its
* pgrp, so naturally it sets its pgrp and gets hosed
* when it gets foregrounded by the parent shell, which
* has restored the tty's pgrp to that of the su
* process).
*/
if (j->state == PSTOPPED &&
(j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0)
j->flags |= JF_SAVEDTTYPGRP;
if (tcsetpgrp(tty_fd, our_pgrp) < 0) {
warningf(true,
"j_waitj: tcsetpgrp(%d, %d) failed: %s",
tty_fd, (int) our_pgrp,
strerror(errno));
}
if (j->state == PSTOPPED) {
j->flags |= JF_SAVEDTTY;
tcgetattr(tty_fd, &j->ttystate);
}
}
#endif /* JOBS */
if (tty_fd >= 0) {
/* Only restore tty settings if job was originally
* started in the foreground. Problems can be
* caused by things like `more foobar &' which will
* typically get and save the shell's vi/emacs tty
* settings before setting up the tty for itself;
* when more exits, it restores the `original'
* settings, and things go down hill from there...
*/
if (j->state == PEXITED && j->status == 0 &&
(j->flags & JF_USETTYMODE)) {
tcgetattr(tty_fd, &tty_state);
} else {
tcsetattr(tty_fd, TCSADRAIN, &tty_state);
/* Don't use tty mode if job is stopped and
* later restarted and exits. Consider
* the sequence:
* vi foo (stopped)
* ...
* stty something
* ...
* fg (vi; ZZ)
* mode should be that of the stty, not what
* was before the vi started.
*/
if (j->state == PSTOPPED)
j->flags &= ~JF_USETTYMODE;
}
}
#ifdef JOBS
//.........这里部分代码省略.........
示例6: main
//.........这里部分代码省略.........
memset(&signals, 0, sizeof(signals));
sigemptyset(&signals.sa_mask);
if (killsig != SIGKILL && killsig != SIGSTOP)
signums[0] = killsig;
for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i ++)
sigaddset(&signals.sa_mask, signums[i]);
signals.sa_handler = sig_handler;
signals.sa_flags = SA_RESTART;
for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i ++)
if (signums[i] != -1 && signums[i] != 0 &&
sigaction(signums[i], &signals, NULL) == -1)
err(EX_OSERR, "sigaction()");
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
pid = fork();
if (pid == -1)
err(EX_OSERR, "fork()");
else if (pid == 0) {
/* child process */
signal(SIGTTIN, SIG_DFL);
signal(SIGTTOU, SIG_DFL);
error = execvp(argv[0], argv);
if (error == -1)
err(EX_UNAVAILABLE, "exec()");
}
if (sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL) == -1)
err(EX_OSERR, "sigprocmask()");
/* parent continues here */
set_interval(first_kill);
for (;;) {
sigemptyset(&signals.sa_mask);
sigsuspend(&signals.sa_mask);
if (sig_chld) {
sig_chld = 0;
while (((cpid = wait(&status)) < 0) && errno == EINTR)
continue;
if (cpid == pid) {
pstat = status;
break;
}
} else if (sig_alrm) {
sig_alrm = 0;
timedout = true;
if (!foreground)
killpg(pgid, killsig);
else
kill(pid, killsig);
if (do_second_kill) {
set_interval(second_kill);
second_kill = 0;
sig_ign = killsig;
killsig = SIGKILL;
} else
break;
} else if (sig_term) {
if (!foreground)
killpg(pgid, killsig);
else
kill(pid, sig_term);
if (do_second_kill) {
set_interval(second_kill);
second_kill = 0;
sig_ign = killsig;
killsig = SIGKILL;
} else
break;
}
}
while (cpid != pid && wait(&pstat) == -1) {
if (errno != EINTR)
err(EX_OSERR, "waitpid()");
}
if (WEXITSTATUS(pstat))
pstat = WEXITSTATUS(pstat);
else if(WIFSIGNALED(pstat))
pstat = 128 + WTERMSIG(pstat);
if (timedout && !preserve)
pstat = EXIT_TIMEOUT;
return (pstat);
}
示例7: ngx_master_process_cycle
//.........这里部分代码省略.........
NGX_PROCESS_RESPAWN);
/*启动缓存索引重建进程,该进程在整个Nginx服务器运行过程中只存在很短的时间,主要用来遍历磁盘上的缓存数据,在内存中建立数据索引,提高Nginx服务器检索缓存的效率*/
ngx_start_cache_manager_processes(cycle, 0);
ngx_new_binary = 0;
delay = 0;
sigio = 0;
live = 1;
for ( ;; ) {
if (delay) {
/*等待工作进程退出的时间*/
if (ngx_sigalrm) {
sigio = 0;
delay *= 2;
ngx_sigalrm = 0;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"termination cycle: %M", delay);
/*初始化一个定时器*/
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = delay / 1000;
itv.it_value.tv_usec = (delay % 1000 ) * 1000;
if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"setitimer() failed");
}
}
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");
/*挂起进程,等待接收到信号,在不向主进程发送信号的情况下,该进程将一直挂起在这里等待*/
sigsuspend(&set);
/*更新缓冲时间*/
ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"wake up, sigio %i", sigio);
/*如果有工作进程异常退出,则调用ngx_reap_children()重启该工作进程*/
if (ngx_reap) {
ngx_reap = 0;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
/*重启工作进程*/
live = ngx_reap_children(cycle);
}
/*如果主进程接收到的是NGX_CMD_TERMINATE信号、SIGTERM信号、SIGINT信号(ngx_terminate=1)或者收到的是NGX_CMD_QUIT信号、SIGQUIT信号(ngx_quit=1),并且工作进程退出,则主进程调用ngx_master_process_exit()函数退出*/
if (!live && (ngx_terminate || ngx_quit)) {
ngx_master_process_exit(cycle);
}
/*处理SIGINT信号*/
if (ngx_terminate) {
if (delay == 0) {
delay = 50;
}
if (sigio) {
sigio--;
示例8: producer
void producer( pid_t ch_pid, int argc, char * argv[] )
{
/*******************************************
* Define producer (parent) process
*******************************************/
printf("\tPRODUCER: pid = %d\n", getpid());
struct sigaction action;
action.sa_handler = SIG_IGN;
sigaction(SIGUSR1, &action, NULL);
/* Read input file */
char buffer[BUFSIZE];
ssize_t count;
int fdin;
/* validate arguments from program call */
if ( argc !=2 )
{
printf( "Usage: %s <input_filename>\n", argv[0] );
exit(1);
}
/* validate input file */
if ( (fdin = open(argv[1], O_RDONLY)) == -1 )
{
perror("Error opening the input file");
exit(2);
}
/* enter while loop to process data from input file */
sigset_t mask;
sigemptyset ( &mask );
while ( (count=read(fdin, buffer, BUFSIZE)) > 0 )
{
/* Copy data from local buffer into shared memory */
memcpy( shmem_ptr->buf, buffer, count );
#ifdef DEBUG
printf("PRODUCER: wrote %zu bytes to shared mem\n", count);
#endif
/* Send signal to consumer */
#ifdef DEBUG
printf("PRODUCER: signal Consumer that shared memory ready to read\n");
#endif
send_rt_signal( ch_pid, SIGUSR1, (int)count );
/* Suspend until signal received from consumer */
#ifdef DEBUG
printf("PRODUCER: suspend until signal received from Consumer...\n");
#endif
sigsuspend( &mask ); /* No signals are masked while waiting */
}
if ( count == -1 ) {
perror ("Error reading input file");
exit(4);
}
close(fdin);
/* Send signal to consumer */
#ifdef DEBUG
printf("PRODUCER: signal Consumer that Producer has reached EOF\n");
#endif
send_rt_signal( ch_pid, SIGUSR1, -1 );
/* Suspend until signal received from consumer */
#ifdef DEBUG
printf("PRODUCER: suspend until signal received from Consumer...\n");
#endif
sigsuspend( &mask ); /* No signals are masked while waiting */
}
示例9: main
//.........这里部分代码省略.........
sigprocmask(SIG_BLOCK, &blockedsigs, NULL);
sigfillset(&unblockedsigs);
sigdelset(&unblockedsigs, SIGTERM);
sigdelset(&unblockedsigs, SIGINT);
sigdelset(&unblockedsigs, SIGHUP);
sigdelset(&unblockedsigs, SIGIO);
sigdelset(&unblockedsigs, SIGCHLD);
if (boot) {
sigdelset(&unblockedsigs, SIGALRM);
}
sigprocmask(SIG_UNBLOCK, &unblockedsigs, NULL);
/* Initialize the retry timeout using the RETRYTIMEOUT setting. */
temp = svGetValue(ifcfg, "RETRYTIMEOUT");
if (temp) {
timeout = atoi(temp);
free(temp);
} else {
timeout = 30;
}
/* Start trying to bring the interface up. */
fork_exec(FALSE, IFUP_PPP, "daemon", device, boot);
while (TRUE) {
/* Wait for a signal. */
if (!theSigterm &&
!theSigint &&
!theSighup &&
!theSigio &&
!theSigchld &&
!theSigalrm) {
sigsuspend(&unblockedsigs);
}
/* If we got SIGTERM or SIGINT, give up and hang up. */
if (theSigterm || theSigint) {
theSigterm = theSigint = 0;
/* If we've already tried to exit this way, use SIGKILL instead
* of SIGTERM, because pppd's just being stubborn. */
if (dying) {
sendsig = SIGKILL;
} else {
sendsig = SIGTERM;
}
dying = TRUE;
/* Get the pid of our child pppd. */
pppLogicalToPhysical(&pppdPid, device, NULL);
/* We don't know what our child pid is. This is very confusing. */
if (!pppdPid) {
failureExit(35);
}
/* Die, pppd, die. */
kill(pppdPid, sendsig);
if (sendsig == SIGKILL) {
kill(-pppdPid, SIGTERM); /* Give it a chance to die nicely, then
kill its whole process group. */
usleep(2500000);
kill(-pppdPid, sendsig);
hangup(ifcfg);
failureExit(32);
示例10: APR_DECLARE
APR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum))
{
sigset_t sig_mask;
#if APR_HAVE_SIGWAIT
int (*sig_func)(int signum) = (int (*)(int))signal_handler;
#endif
/* This thread will be the one responsible for handling signals */
sigfillset(&sig_mask);
/* On certain platforms, sigwait() returns EINVAL if any of various
* unblockable signals are included in the mask. This was first
* observed on AIX and Tru64.
*/
#ifdef SIGKILL
sigdelset(&sig_mask, SIGKILL);
#endif
#ifdef SIGSTOP
sigdelset(&sig_mask, SIGSTOP);
#endif
#ifdef SIGCONT
sigdelset(&sig_mask, SIGCONT);
#endif
#ifdef SIGWAITING
sigdelset(&sig_mask, SIGWAITING);
#endif
/* no synchronous signals should be in the mask passed to sigwait() */
remove_sync_sigs(&sig_mask);
/* On AIX (4.3.3, at least), sigwait() won't wake up if the high-
* order bit of the second word of flags is turned on. sigdelset()
* returns an error when trying to turn this off, so we'll turn it
* off manually.
*
* Note that the private fields differ between 32-bit and 64-bit
* and even between _ALL_SOURCE and !_ALL_SOURCE. Except that on
* AIX 4.3 32-bit builds and 64-bit builds use the same definition.
*
* Applicable AIX fixes such that this is no longer needed:
*
* APAR IY23096 for AIX 51B, fix included in AIX 51C, and
* APAR IY24162 for 43X.
*/
#if defined(_AIX)
#if defined(__64BIT__) && defined(_AIXVERSION_510)
#ifdef _ALL_SOURCE
sig_mask.ss_set[3] &= 0x7FFFFFFF;
#else /* not _ALL_SOURCE */
sig_mask.__ss_set[3] &= 0x7FFFFFFF;
#endif
#else /* not 64-bit build, or 64-bit build on 4.3 */
#ifdef _ALL_SOURCE
sig_mask.hisigs &= 0x7FFFFFFF;
#else /* not _ALL_SOURCE */
sig_mask.__hisigs &= 0x7FFFFFFF;
#endif
#endif
#endif /* _AIX */
while (1) {
#if APR_HAVE_SIGWAIT
int signal_received;
if (apr_sigwait(&sig_mask, &signal_received) != 0)
{
/* handle sigwait() error here */
}
if (sig_func(signal_received) == 1) {
return APR_SUCCESS;
}
#elif HAVE_SIGSUSPEND
sigsuspend(&sig_mask);
#else
#error No apr_sigwait() and no sigsuspend()
#endif
}
}
示例11: suspend_thread
static void
suspend_thread (SgenThreadInfo *info, void *context)
{
int stop_count;
#ifndef USE_MONO_CTX
gpointer regs [ARCH_NUM_REGS];
#endif
MonoContext ctx;
gpointer stack_start;
info->client_info.stopped_domain = mono_domain_get ();
info->client_info.signal = 0;
stop_count = sgen_global_stop_count;
/* duplicate signal */
if (0 && info->client_info.stop_count == stop_count)
return;
#ifdef USE_MONO_CTX
if (context) {
mono_sigctx_to_monoctx (context, &ctx);
info->client_info.stopped_ip = MONO_CONTEXT_GET_IP (&ctx);
stack_start = (((guint8 *) MONO_CONTEXT_GET_SP (&ctx)) - REDZONE_SIZE);
} else {
info->client_info.stopped_ip = NULL;
stack_start = NULL;
}
#else
info->client_info.stopped_ip = context ? (gpointer) ARCH_SIGCTX_IP (context) : NULL;
stack_start = context ? (char*) ARCH_SIGCTX_SP (context) - REDZONE_SIZE : NULL;
#endif
/* If stack_start is not within the limits, then don't set it
in info and we will be restarted. */
if (stack_start >= info->client_info.stack_start_limit && stack_start <= info->client_info.stack_end) {
info->client_info.stack_start = stack_start;
#ifdef USE_MONO_CTX
if (context) {
memcpy (&info->client_info.ctx, &ctx, sizeof (MonoContext));
} else {
memset (&info->client_info.ctx, 0, sizeof (MonoContext));
}
#else
if (context) {
ARCH_COPY_SIGCTX_REGS (regs, context);
memcpy (&info->client_info.regs, regs, sizeof (info->client_info.regs));
} else {
memset (&info->client_info.regs, 0, sizeof (info->client_info.regs));
}
#endif
} else {
g_assert (!info->client_info.stack_start);
}
/* Notify the JIT */
if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
mono_gc_get_gc_callbacks ()->thread_suspend_func (info->client_info.runtime_data, context, NULL);
SGEN_LOG (4, "Posting suspend_ack_semaphore for suspend from %p %p", info, (gpointer) (gsize) mono_native_thread_id_get ());
/*
Block the restart signal.
We need to block the restart signal while posting to the suspend_ack semaphore or we race to sigsuspend,
which might miss the signal and get stuck.
*/
pthread_sigmask (SIG_BLOCK, &suspend_ack_signal_mask, NULL);
/* notify the waiting thread */
SGEN_SEMAPHORE_POST (suspend_ack_semaphore_ptr);
info->client_info.stop_count = stop_count;
/* wait until we receive the restart signal */
do {
info->client_info.signal = 0;
sigsuspend (&suspend_signal_mask);
} while (info->client_info.signal != restart_signal_num);
/* Unblock the restart signal. */
pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL);
SGEN_LOG (4, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer) (gsize) mono_native_thread_id_get ());
/* notify the waiting thread */
SGEN_SEMAPHORE_POST (suspend_ack_semaphore_ptr);
}
示例12: main
int
main(int argc, char **argv)
{
char buf[1024], *cp, c;
int error, desc, rv;
long scval;
sigset_t ss;
struct sigaction sa;
void *region;
size_t i, psize;
#ifndef _POSIX_SHARED_MEMORY_OBJECTS
printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n");
#else
printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n",
(long)_POSIX_SHARED_MEMORY_OBJECTS - 0);
if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1)
printf("***Indicates this feature may be unsupported!\n");
#endif
errno = 0;
scval = sysconf(_SC_SHARED_MEMORY_OBJECTS);
if (scval == -1 && errno != 0) {
err(1, "sysconf(_SC_SHARED_MEMORY_OBJECTS)");
} else {
printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n",
scval);
if (scval == -1)
printf("***Indicates this feature is unsupported!\n");
}
errno = 0;
scval = sysconf(_SC_PAGESIZE);
if (scval == -1 && errno != 0) {
err(1, "sysconf(_SC_PAGESIZE)");
} else if (scval <= 0 || (size_t)psize != psize) {
warnx("bogus return from sysconf(_SC_PAGESIZE): %ld",
scval);
psize = 4096;
} else {
printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval);
psize = scval;
}
argc--, argv++;
if (*argv) {
strncat(buf, *argv, (sizeof buf) - 1);
desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
} else {
do {
/*
* Can't use mkstemp for obvious reasons...
*/
strcpy(buf, "/tmp/shmtest.XXXXXXXXXXXX");
mktemp(buf);
desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
} while (desc < 0 && errno == EEXIST);
}
if (desc < 0)
err(1, "shm_open");
if (shm_unlink(buf) < 0)
err(1, "shm_unlink");
if (ftruncate(desc, (off_t)psize) < 0)
err(1, "ftruncate");
region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED,
desc, (off_t)0);
if (region == MAP_FAILED)
err(1, "mmap");
memset(region, '\377', psize);
sa.sa_flags = 0;
sa.sa_handler = ignoreit;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGUSR1, &sa, (struct sigaction *)0) < 0)
err(1, "sigaction");
sigemptyset(&ss);
sigaddset(&ss, SIGUSR1);
if (sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) < 0)
err(1, "sigprocmask");
rv = fork();
if (rv < 0) {
err(1, "fork");
} else if (rv == 0) {
sigemptyset(&ss);
sigsuspend(&ss);
for (cp = region; cp < (char *)region + psize; cp++) {
if (*cp != '\151')
_exit(1);
}
if (lseek(desc, 0, SEEK_SET) == -1)
_exit(1);
for (i = 0; i < psize; i++) {
error = read(desc, &c, 1);
//.........这里部分代码省略.........
示例13: eval
/*
* eval - Evaluate the command line that the user has just typed in
*
* If the user has requested a built-in command (quit, jobs, bg or fg)
* then execute it immediately. Otherwise, fork a child process and
* run the job in the context of the child. If the job is running in
* the foreground, wait for it to terminate and then return. Note:
* each child process must have a unique process group ID so that our
* background children don't receive SIGINT (SIGTSTP) from the kernel
* when we type ctrl-c (ctrl-z) at the keyboard.
*/
void
eval(char *cmdline)
{
int bg; /* should the job run in bg or fg? */
struct cmdline_tokens tok;
int temp;
pid_t pid;
// variables to be used for blocking and unblocking signals
sigset_t sigs;
sigset_t sigmask;
sigset_t wmask;
sigemptyset(&sigmask);
int jobID;
struct job_t *new_job;
/* Parse command line */
bg = parseline(cmdline, &tok);
if (bg == -1) /* parsing error */
return;
if (tok.argv[0] == NULL) /* ignore empty lines */
return;
// If user enters builtin command quit
// normally exits
else if(tok.builtins == BUILTIN_QUIT)
exit(0);
// If user enters builtin command jobs
// Lists all the current running and stopped jobs
else if(tok.builtins == BUILTIN_JOBS)
{
if(tok.outfile == NULL)
listjobs(job_list,1);
else
{
temp = open(tok.outfile,O_WRONLY);
listjobs(job_list,temp);
}
}
// If user did not enter any built in commands
else if(tok.builtins == BUILTIN_NONE)
{
//initialize signals and block
sigemptyset(&sigs);
sigaddset(&sigs, SIGINT);
sigaddset(&sigs, SIGTSTP);
sigaddset(&sigs, SIGCHLD);
sigprocmask(SIG_BLOCK, &sigs, NULL);
// I/O redirection
if((pid = fork()) == 0)
{
if(tok.infile != NULL)
dup2(open(tok.infile, O_RDONLY), 0);
if(tok.outfile != NULL)
dup2(open(tok.outfile, O_WRONLY), 0);
setpgid(0, 0);
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
if(execve(tok.argv[0], tok.argv, environ) < 0) //execute user command
{
printf("%s: Command not found. \n", tok.argv[0]);
exit(0);
}
}
if(!addjob(job_list, pid, bg ? BG : FG, cmdline))
return;
if(!bg)
while(fgpid(job_list)) // wait for foreground job to finish
sigsuspend(&sigmask);
else
printf("[%d] (%d) %s\n",pid2jid(pid),pid,cmdline);
sigprocmask(SIG_UNBLOCK,&sigs,NULL);
}
// If user enters builtin command FG (Foreground)
if(tok.builtins == BUILTIN_FG)
{
//.........这里部分代码省略.........
示例14: eval
/*
* eval - Evaluate the command line that the user has just typed in
*
* If the user has requested a built-in command (quit, jobs, bg or fg)
* then execute it immediately. Otherwise, fork a child process and
* run the job in the context of the child. If the job is running in
* the foreground, wait for it to terminate and then return. Note:
* each child process must have a unique process group ID so that our
* background children don't receive SIGINT (SIGTSTP) from the kernel
* when we type ctrl-c (ctrl-z) at the keyboard.
*/
void
eval(char *cmdline)
{
int bg; /* should the job run in bg or fg? */
struct cmdline_tokens tok;
int fd_in = STDIN_FILENO;
int fd_out = STDOUT_FILENO;
//int status;
sigset_t mask, prev_mask;
struct job_t *job;
pid_t pid;
/* Parse command line */
bg = parseline(cmdline, &tok);
if (bg == -1) /* parsing error */
return;
if (tok.argv[0] == NULL) /* ignore empty lines */
return;
//Handle IO redirection
if(tok.infile != NULL ) {
if( (fd_in = open(tok.infile,O_RDONLY, 0)) < 0 )
app_error("cannot open input file");
}
if(tok.outfile != NULL ) {
if( (fd_out = open(tok.outfile,O_WRONLY|O_CREAT, 0644)) < 0 )
app_error("cannot open output file");
}
switch(tok.builtins) {
case BUILTIN_QUIT:
exit(0);
break;
case BUILTIN_JOBS:
listjobs(job_list,fd_out);
break;
case BUILTIN_BG:
if(tok.argc < 2)
app_error("lack of argument: PID or %%jobid");
if(tok.argv[1][0] == '%')
job = getjobjid(job_list,atoi(tok.argv[1]+1));
else
job = getjobpid(job_list,atoi(tok.argv[1]));
if( !job )
app_error("no such process or job");
//Set job state to BG and send SIGCONT to its process group
job->state = BG;
printf("[%d] (%d) %s\n", job->jid, job->pid, job->cmdline);
kill(-job->pid,SIGCONT);
break;
case BUILTIN_FG:
if(tok.argc < 2)
app_error("lack of argument: PID or %%jobid");
if(tok.argv[1][0] == '%')
job = getjobjid(job_list,atoi(tok.argv[1]+1));
else
job = getjobpid(job_list,atoi(tok.argv[1]));
if( !job )
app_error("no such processs or job");
//Set job state to FG, send SIGCONT to its process, bring it to the front
job->state = FG;
kill(-job->pid, SIGCONT);
//wait the fg process by a sigsuspend
sigemptyset(&mask);
if(!bg)
while( fgpid(job_list) > 0 )
sigsuspend(&mask);
break;
case BUILTIN_NONE:
//Block SIGINT, SIGTSTP, SIGCHLD to avoid race
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGTSTP);
sigprocmask(SIG_BLOCK, &mask, &prev_mask);
//Child
if((pid = fork()) == 0) {
//Make SIGINT only send to tsh
//.........这里部分代码省略.........
示例15: consumer
void consumer( void )
{
/*******************************************
* Define consumer (child) process
*******************************************/
printf("\tCONSUMER: pid = %d\n", getpid());
consumer_done = 0;
struct sigaction action;
action.sa_handler = SIG_IGN;
sigaction(SIGUSR2, &action, NULL);
/* Reuse key set in main to get the segment id of the
segment that the parent process created. The size parameter is set
to zero, and the flag to IPC_ALLOC, indicating that the segment is
not being created here, it already exists
*/
shmem_id = shmget (key, 0, 0);
if (shmem_id == -1)
{
perror("child shmget failed");
exit(1);
}
#ifdef DEBUG
printf("Consumer: Got shmem id = %d\n", shmem_id);
#endif
/* Now attach this segment into the child address space */
shmem_ptr = shmat (shmem_id, (void *) NULL, flag);
if (shmem_ptr == (void *) -1)
{
perror("child shmat failed");
exit(2);
}
#ifdef DEBUG
printf("Consumer: Got ptr = %p\n", shmem_ptr);
#endif
/* open output file */
mode_t perms;
perms = 0740;
if ( (fdout = open ("output", (O_WRONLY | O_CREAT), perms)) == -1 )
{
perror("Error in creating output file");
exit(3);
}
/* Suspend until signal received from producer */
sigset_t mask;
sigemptyset ( &mask );
while ( consumer_done == 0 )
{
#ifdef DEBUG
printf("CONSUMER: suspend until signal received from Producer...\n");
#endif
sigsuspend( &mask ); /* No signals are masked while waiting */
}
/* close the file */
close(fdout);
/* compute metrics from data transfer */
struct timespec ts_now;
float d_xfr_t;
clock_gettime( CLOCK_MONOTONIC, &ts_now );
d_xfr_t = diff_time( &(shmem_ptr->ts), &ts_now );
printf("\tData transfer completed in %f ms\n", d_xfr_t);
/* done with the program, so detach the shared segment */
shmdt( (void *)shmem_ptr);
/* send signal to producer to indicate transfer complete */
#ifdef DEBUG
printf("CONSUMER: signal Producer that data transfer is complete\n");
#endif
send_rt_signal( getppid(), SIGUSR2, 0 );
}