Ejemplo n.º 1
0
static ngx_int_t
ngx_event_process_init(ngx_cycle_t *cycle)
{
    ngx_uint_t           m, i;
    ngx_event_t         *rev, *wev;
    ngx_listening_t     *ls;
    ngx_connection_t    *c, *next, *old;
    ngx_core_conf_t     *ccf;
    ngx_event_conf_t    *ecf;
    ngx_event_module_t  *module;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);

    if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
        ngx_use_accept_mutex = 1;
        ngx_accept_mutex_held = 0;
        ngx_accept_mutex_delay = ecf->accept_mutex_delay;

    } else {
        ngx_use_accept_mutex = 0;
    }

#if (NGX_WIN32)

    /*
     * disable accept mutex on win32 as it may cause deadlock if
     * grabbed by a process which can't accept connections
     */

    ngx_use_accept_mutex = 0;

#endif

    ngx_queue_init(&ngx_posted_accept_events);
    ngx_queue_init(&ngx_posted_events);

    if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
        return NGX_ERROR;
    }

    for (m = 0; ngx_modules[m]; m++) {
        if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
            continue;
        }

        if (ngx_modules[m]->ctx_index != ecf->use) {
            continue;
        }

        module = ngx_modules[m]->ctx;

        if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
            /* fatal */
            exit(2);
        }

        break;
    }

#if !(NGX_WIN32)

    if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
        struct sigaction  sa;
        struct itimerval  itv;

        ngx_memzero(&sa, sizeof(struct sigaction));
        sa.sa_handler = ngx_timer_signal_handler;
        sigemptyset(&sa.sa_mask);

        if (sigaction(SIGALRM, &sa, NULL) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "sigaction(SIGALRM) failed");
            return NGX_ERROR;
        }

        itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
        itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
        itv.it_value.tv_sec = ngx_timer_resolution / 1000;
        itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;

        if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setitimer() failed");
        }
    }

    if (ngx_event_flags & NGX_USE_FD_EVENT) {
        struct rlimit  rlmt;

        if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "getrlimit(RLIMIT_NOFILE) failed");
            return NGX_ERROR;
        }

        cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;

        cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
                                  cycle->log);
        if (cycle->files == NULL) {
            return NGX_ERROR;
        }
    }

#endif

    cycle->connections =
        ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
    if (cycle->connections == NULL) {
        return NGX_ERROR;
    }

    c = cycle->connections;

    cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                   cycle->log);
    if (cycle->read_events == NULL) {
        return NGX_ERROR;
    }

    rev = cycle->read_events;
    for (i = 0; i < cycle->connection_n; i++) {
        rev[i].closed = 1;
        rev[i].instance = 1;
    }

    cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                    cycle->log);
    if (cycle->write_events == NULL) {
        return NGX_ERROR;
    }

    wev = cycle->write_events;
    for (i = 0; i < cycle->connection_n; i++) {
        wev[i].closed = 1;
    }

    i = cycle->connection_n;
    next = NULL;

    do {
        i--;

        c[i].data = next;
        c[i].read = &cycle->read_events[i];
        c[i].write = &cycle->write_events[i];
        c[i].fd = (ngx_socket_t) -1;

        next = &c[i];
    } while (i);

    cycle->free_connections = next;
    cycle->free_connection_n = cycle->connection_n;

    /* for each listening socket */

    ls = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {

#if (NGX_HAVE_REUSEPORT)
        if (ls[i].reuseport && ls[i].worker != ngx_worker) {
            continue;
        }
#endif

        c = ngx_get_connection(ls[i].fd, cycle->log);

        if (c == NULL) {
            return NGX_ERROR;
        }

        c->log = &ls[i].log;

        c->listening = &ls[i];
        ls[i].connection = c;

#if (NGX_QUIC)
        if (ls[i].quic) {
            rev = c->read;
            c->recv = ngx_recv;
            rev->handler = ngx_quic_recv;
            rev->log = c->log;
            if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR)
                return NGX_ERROR;
            continue;
        }
#endif

        rev = c->read;

        rev->log = c->log;
        rev->accept = 1;

#if (NGX_HAVE_DEFERRED_ACCEPT)
        rev->deferred_accept = ls[i].deferred_accept;
#endif

        if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
            if (ls[i].previous) {

                /*
                 * delete the old accept events that were bound to
                 * the old cycle read events array
                 */

                old = ls[i].previous->connection;

                if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
                    == NGX_ERROR)
                {
                    return NGX_ERROR;
                }

                old->fd = (ngx_socket_t) -1;
            }
        }

#if (NGX_WIN32)

        if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
            ngx_iocp_conf_t  *iocpcf;

            rev->handler = ngx_event_acceptex;

            if (ngx_use_accept_mutex) {
                continue;
            }

            if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
                return NGX_ERROR;
            }

            ls[i].log.handler = ngx_acceptex_log_error;

            iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
            if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
                == NGX_ERROR)
            {
                return NGX_ERROR;
            }

        } else {
            rev->handler = ngx_event_accept;

            if (ngx_use_accept_mutex) {
                continue;
            }

            if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                return NGX_ERROR;
            }
        }

#else

        rev->handler = ngx_event_accept;

        if (ngx_use_accept_mutex
#if (NGX_HAVE_REUSEPORT)
            && !ls[i].reuseport
#endif
           )
        {
            continue;
        }

        if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
            return NGX_ERROR;
        }

#endif

    }

    return NGX_OK;
}
Ejemplo n.º 2
0
ARMword
ARMul_DoProg (ARMul_State * state)
{
	ARMword pc = 0;

	/*
	 * 2007-01-24 removed the term-io functions by Anthony Lee,
	 * moved to "device/uart/skyeye_uart_stdio.c".
	 */

//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
#ifdef DBCT_TEST_SPEED
	{
		if (!dbct_test_speed_state) {
			//init timer
			struct itimerval	value;
			struct sigaction	act;

			dbct_test_speed_state = state;
			state->instr_count = 0;
			act.sa_handler = dbct_test_speed_sig;
			act.sa_flags = SA_RESTART;
			//cygwin don't support ITIMER_VIRTUAL or ITIMER_PROF
#ifndef __CYGWIN__
			if (sigaction(SIGVTALRM, &act, NULL) == -1) {
#else
			if (sigaction(SIGALRM, &act, NULL) == -1) {
#endif	//__CYGWIN__
				fprintf(stderr, "init timer error.\n");
				skyeye_exit(-1);
			}
			if (skyeye_config.dbct_test_speed_sec) {
				value.it_value.tv_sec = skyeye_config.dbct_test_speed_sec;
			}
			else {
				value.it_value.tv_sec = DBCT_TEST_SPEED_SEC;
			}
			printf("dbct_test_speed_sec = %ld\n", value.it_value.tv_sec);
			value.it_value.tv_usec = 0;
			value.it_interval.tv_sec = 0; 
			value.it_interval.tv_usec = 0;
#ifndef __CYGWIN__
			if (setitimer(ITIMER_VIRTUAL, &value, NULL) == -1) {
#else
			if (setitimer(ITIMER_REAL, &value, NULL) == -1) {
#endif	//__CYGWIN__
				fprintf(stderr, "init timer error.\n");
				skyeye_exit(-1);
			}
		}
	}
#endif	//DBCT_TEST_SPEED
//AJ2D--------------------------------------------------------------------------
	state->Emulate = RUN;
	while (state->Emulate != STOP) {
		state->Emulate = RUN;

		/*ywc 2005-03-31 */
		if (state->prog32Sig && ARMul_MODE32BIT) {
#ifdef DBCT
			if (skyeye_config.no_dbct) {
				pc = ARMul_Emulate32 (state);
			}
			else {
				pc = ARMul_Emulate32_dbct (state);
			}
#else
			pc = ARMul_Emulate32 (state);
#endif
		}

		else {
			pc = ARMul_Emulate26 (state);
		}
		//chy 2006-02-22, should test debugmode first
		//chy 2006-04-14, put below codes in ARMul_Emulate
#if 0
		if(debugmode)
		  if(remote_interrupt())
			state->Emulate = STOP;
#endif
	}

	/*
	 * 2007-01-24 removed the term-io functions by Anthony Lee,
	 * moved to "device/uart/skyeye_uart_stdio.c".
	 */

	return (pc);
}

/***************************************************************************\
* Emulate the execution of one instruction.  Start the correct emulator     *
* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the   *
* address of the instruction that is executed.                              *
\***************************************************************************/

ARMword
ARMul_DoInstr (ARMul_State * state)
{
	ARMword pc = 0;

	state->Emulate = ONCE;

	/*ywc 2005-03-31 */
	if (state->prog32Sig && ARMul_MODE32BIT) {
#ifdef DBCT
		if (skyeye_config.no_dbct) {
			pc = ARMul_Emulate32 (state);
		}
		else {
//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
#ifndef DBCT_GDBRSP
			printf("DBCT GDBRSP function switch is off.\n");
			printf("To use this function, open \"#define DBCT_GDBRSP\" in arch/arm/common/armdefs.h & recompile skyeye.\n");
			skyeye_exit(-1);
#endif	//DBCT_GDBRSP
//AJ2D--------------------------------------------------------------------------
			pc = ARMul_Emulate32_dbct (state);
		}
#else
		pc = ARMul_Emulate32 (state);
#endif
	}

	else
		pc = ARMul_Emulate26 (state);

	return (pc);
}

/***************************************************************************\
* This routine causes an Abort to occur, including selecting the correct    *
* mode, register bank, and the saving of registers.  Call with the          *
* appropriate vector's memory address (0,4,8 ....)                          *
\***************************************************************************/

void
ARMul_Abort (ARMul_State * state, ARMword vector)
{
	ARMword temp;
	int isize = INSN_SIZE;
	int esize = (TFLAG ? 0 : 4);
	int e2size = (TFLAG ? -4 : 0);

	state->Aborted = FALSE;

	if (state->prog32Sig)
		if (ARMul_MODE26BIT)
			temp = R15PC;
		else
			temp = state->Reg[15];
	else
		temp = R15PC | ECC | ER15INT | EMODE;

	switch (vector) {
	case ARMul_ResetV:	/* RESET */
		SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
			  0);
		break;
	case ARMul_UndefinedInstrV:	/* Undefined Instruction */
		SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
			  isize);
		break;
	case ARMul_SWIV:	/* Software Interrupt */
		SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
			  isize);
		break;
	case ARMul_PrefetchAbortV:	/* Prefetch Abort */
		state->AbortAddr = 1;
		SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
			  esize);
		break;
	case ARMul_DataAbortV:	/* Data Abort */
		SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
			  e2size);
		break;
	case ARMul_AddrExceptnV:	/* Address Exception */
		SETABORT (IBIT, SVC26MODE, isize);
		break;
	case ARMul_IRQV:	/* IRQ */
		//chy 2003-09-02 the if sentence seems no use
#if 0
		if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
		    || (temp & ARMul_CP13_R0_IRQ))
#endif
			SETABORT (IBIT,
				  state->prog32Sig ? IRQ32MODE : IRQ26MODE,
				  esize);
		break;
	case ARMul_FIQV:	/* FIQ */
		//chy 2003-09-02 the if sentence seems no use
#if 0
		if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
		    || (temp & ARMul_CP13_R0_FIQ))
#endif
			SETABORT (INTBITS,
				  state->prog32Sig ? FIQ32MODE : FIQ26MODE,
				  esize);
		break;
	}

	if (ARMul_MODE32BIT) {
		if (state->mmu.control & CONTROL_VECTOR)
			vector += 0xffff0000;	//for v4 high exception  address
		if (state->vector_remap_flag)
			vector += state->vector_remap_addr; /* support some remap function in LPC processor */
		ARMul_SetR15 (state, vector);
	}
	else
		ARMul_SetR15 (state, R15CCINTMODE | vector);
}
Ejemplo n.º 3
0
void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
    char              *title;
    u_char            *p;
    size_t             size;
    ngx_int_t          i;
    ngx_uint_t         n, sigio;
    sigset_t           set;
    struct itimerval   itv;
    ngx_uint_t         live;
    ngx_msec_t         delay;
    ngx_listening_t   *ls;
    ngx_core_conf_t   *ccf;

    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigaddset(&set, SIGALRM);
    sigaddset(&set, SIGIO);
    sigaddset(&set, SIGINT);
    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));

    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

    sigemptyset(&set);


    size = sizeof(master_process);

    for (i = 0; i < ngx_argc; i++) {
        size += ngx_strlen(ngx_argv[i]) + 1;
    }

    title = ngx_pnalloc(cycle->pool, size);
    if (title == NULL) {
        /* fatal */
        exit(2);
    }

    p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
    for (i = 0; i < ngx_argc; i++) {
        *p++ = ' ';
        p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
    }

    ngx_setproctitle(title);


    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    ngx_start_worker_processes(cycle, ccf->worker_processes,
                               NGX_PROCESS_RESPAWN);
    ngx_start_cache_manager_processes(cycle, 0);
    
    ngx_start_session_manager_processes(cycle, 0);
    
    ngx_start_ip_blacklist_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: %d", 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);

        if (ngx_reap) {
            ngx_reap = 0;
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");

            live = ngx_reap_children(cycle);
        }

        if (!live && (ngx_terminate || ngx_quit)) {
            ngx_master_process_exit(cycle);
        }

        if (ngx_terminate) {
            if (delay == 0) {
                delay = 50;
            }

            if (sigio) {
                sigio--;
                continue;
            }

            sigio = ccf->worker_processes + 2 /* cache processes */;

            if (delay > 1000) {
                ngx_signal_worker_processes(cycle, SIGKILL);
            } else {
                ngx_signal_worker_processes(cycle,
                                       ngx_signal_value(NGX_TERMINATE_SIGNAL));
            }

            continue;
        }

        if (ngx_quit) {
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));

            ls = cycle->listening.elts;
            for (n = 0; n < cycle->listening.nelts; n++) {
                if (ngx_close_socket(ls[n].fd) == -1) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                                  ngx_close_socket_n " %V failed",
                                  &ls[n].addr_text);
                }
            }
            cycle->listening.nelts = 0;

            continue;
        }

        if (ngx_reconfigure) {
            ngx_reconfigure = 0;

            if (ngx_new_binary) {
                ngx_start_worker_processes(cycle, ccf->worker_processes,
                                           NGX_PROCESS_RESPAWN);
                ngx_start_cache_manager_processes(cycle, 0);
                ngx_start_session_manager_processes(cycle, 0);
                ngx_start_ip_blacklist_manager_processes(cycle, 0);
                ngx_noaccepting = 0;

                continue;
            }

            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");

            cycle = ngx_init_cycle(cycle);
            if (cycle == NULL) {
                cycle = (ngx_cycle_t *) ngx_cycle;
                continue;
            }

            ngx_cycle = cycle;
            ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                                   ngx_core_module);
            ngx_start_worker_processes(cycle, ccf->worker_processes,
                                       NGX_PROCESS_JUST_RESPAWN);
            ngx_start_cache_manager_processes(cycle, 1);
            ngx_start_session_manager_processes(cycle, 1);
            ngx_start_ip_blacklist_manager_processes(cycle, 1);

            /* allow new processes to start */
            ngx_msleep(100);

            live = 1;
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
        }

        if (ngx_restart) {
            ngx_restart = 0;
            ngx_start_worker_processes(cycle, ccf->worker_processes,
                                       NGX_PROCESS_RESPAWN);
            ngx_start_cache_manager_processes(cycle, 0);
            ngx_start_session_manager_processes(cycle, 0);
            ngx_start_ip_blacklist_manager_processes(cycle, 0);
            live = 1;
        }

        if (ngx_reopen) {
            ngx_reopen = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
            ngx_reopen_files(cycle, ccf->user);
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_REOPEN_SIGNAL));
        }

        if (ngx_change_binary) {
            ngx_change_binary = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
            ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
        }

        if (ngx_noaccept) {
            ngx_noaccept = 0;
            ngx_noaccepting = 1;
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
        }
    }
}
Ejemplo n.º 4
0
// ngx_event_core_module模块的init_process()回调函数。
static ngx_int_t
ngx_event_process_init(ngx_cycle_t *cycle)
{
    ngx_uint_t           m, i;
    ngx_event_t         *rev, *wev;
    ngx_listening_t     *ls;
    ngx_connection_t    *c, *next, *old;
    ngx_core_conf_t     *ccf;
    ngx_event_conf_t    *ecf;
    ngx_event_module_t  *module;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);

    if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
        ngx_use_accept_mutex = 1;
        ngx_accept_mutex_held = 0;
        ngx_accept_mutex_delay = ecf->accept_mutex_delay;

    } else {
        ngx_use_accept_mutex = 0;
    }

#if (NGX_WIN32)

    /*
     * disable accept mutex on win32 as it may cause deadlock if
     * grabbed by a process which can't accept connections
     */

    ngx_use_accept_mutex = 0;

#endif

#if (NGX_THREADS)
    ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
    if (ngx_posted_events_mutex == NULL) {
        return NGX_ERROR;
    }
#endif

    // 调用定时器初始化函数。
    if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
        return NGX_ERROR;
    }


    // 调用被选用事件模型的初始化函数。
    for (m = 0; ngx_modules[m]; m++) {
        if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
            continue;
        }

        if (ngx_modules[m]->ctx_index != ecf->use) {
            continue;
        }

        module = ngx_modules[m]->ctx;

        if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
            /* fatal */
            exit(2);
        }

        break;
    }

#if !(NGX_WIN32)
    // 如果配置文件里设置timer_resolution字段不为0,修改SIGALRM信号的处理函数为ngx_timer_signal_handler。
    // 并设置以timer_resolution为间隔定时向当前进程发送SIGALRM信号。
    if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
        struct sigaction  sa;
        struct itimerval  itv;

        ngx_memzero(&sa, sizeof(struct sigaction));
        sa.sa_handler = ngx_timer_signal_handler;
        sigemptyset(&sa.sa_mask);

        if (sigaction(SIGALRM, &sa, NULL) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "sigaction(SIGALRM) failed");
            return NGX_ERROR;
        }

        itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
        itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
        itv.it_value.tv_sec = ngx_timer_resolution / 1000;
        itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;

        if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "setitimer() failed");
        }
    }

    if (ngx_event_flags & NGX_USE_FD_EVENT) {
    // epoll事件模型不会进入这个分支。
        struct rlimit  rlmt;

        if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "getrlimit(RLIMIT_NOFILE) failed");
            return NGX_ERROR;
        }

        cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;

        cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
                                  cycle->log);
        if (cycle->files == NULL) {
            return NGX_ERROR;
        }
    }

#endif

    // 预分配ngx_cycle->connections, ngx_cycle->read_events和ngx_cycle->write_events数组,
    // 并做相应初始化。
    cycle->connections =
        ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
    if (cycle->connections == NULL) {
        return NGX_ERROR;
    }

    c = cycle->connections;

    cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                   cycle->log);
    if (cycle->read_events == NULL) {
        return NGX_ERROR;
    }

    rev = cycle->read_events;
    for (i = 0; i < cycle->connection_n; i++) {
        rev[i].closed = 1;
        rev[i].instance = 1;
#if (NGX_THREADS)
        rev[i].lock = &c[i].lock;
        rev[i].own_lock = &c[i].lock;
#endif
    }

    cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
                                    cycle->log);
    if (cycle->write_events == NULL) {
        return NGX_ERROR;
    }

    wev = cycle->write_events;
    for (i = 0; i < cycle->connection_n; i++) {
        wev[i].closed = 1;
#if (NGX_THREADS)
        wev[i].lock = &c[i].lock;
        wev[i].own_lock = &c[i].lock;
#endif
    }

    i = cycle->connection_n;
    next = NULL;

    do {
        i--;

        c[i].data = next;
        c[i].read = &cycle->read_events[i];
        c[i].write = &cycle->write_events[i];
        c[i].fd = (ngx_socket_t) -1;

        next = &c[i];

#if (NGX_THREADS)
        c[i].lock = 0;
#endif
    } while (i);

    // 初始化ngx_cycle->free_connections链表。
    cycle->free_connections = next;
    cycle->free_connection_n = cycle->connection_n;

    /* for each listening socket */

    // 初始化ngx_cycle->listening数组里的(*ngx_listening_t)->connection指向的对象。
    // 并将这个连接对象的读取事件加入到等待事件中。
    ls = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {

        c = ngx_get_connection(ls[i].fd, cycle->log);

        if (c == NULL) {
            return NGX_ERROR;
        }

        c->log = &ls[i].log;

        c->listening = &ls[i];
        ls[i].connection = c;

        rev = c->read;

        rev->log = c->log;
        rev->accept = 1;

#if (NGX_HAVE_DEFERRED_ACCEPT)
        rev->deferred_accept = ls[i].deferred_accept;
#endif

        if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
            if (ls[i].previous) {

                /*
                 * delete the old accept events that were bound to
                 * the old cycle read events array
                 */

                old = ls[i].previous->connection;

                if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
                    == NGX_ERROR)
                {
                    return NGX_ERROR;
                }

                old->fd = (ngx_socket_t) -1;
            }
        }

#if (NGX_WIN32)

        if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
            ngx_iocp_conf_t  *iocpcf;

            rev->handler = ngx_event_acceptex;

            if (ngx_use_accept_mutex) {
                continue;
            }

            if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
                return NGX_ERROR;
            }

            ls[i].log.handler = ngx_acceptex_log_error;

            iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
            if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
                == NGX_ERROR)
            {
                return NGX_ERROR;
            }

        } else {
            rev->handler = ngx_event_accept;

            if (ngx_use_accept_mutex) {
                continue;
            }

            if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                return NGX_ERROR;
            }
        }

#else

        rev->handler = ngx_event_accept;

        if (ngx_use_accept_mutex) {
            continue;
        }

        if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
            if (ngx_add_conn(c) == NGX_ERROR) {
                return NGX_ERROR;
            }

        } else {
            if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
                return NGX_ERROR;
            }
        }

#endif

    }

    return NGX_OK;
}
Ejemplo n.º 5
0
void setup(int icmp_sock)
{
	int hold;
	struct timeval tv;

	if ((options & F_FLOOD) && !(options & F_INTERVAL))
		interval = 0;

	if (uid && interval < MINUSERINTERVAL) {
		fprintf(stderr, "ping: cannot flood; minimal interval, allowed for user, is %dms\n", MINUSERINTERVAL);
		exit(2);
	}

	if (interval >= INT_MAX/preload) {
		fprintf(stderr, "ping: illegal preload and/or interval\n");
		exit(2);
	}

	hold = 1;
	if (options & F_SO_DEBUG)
		setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG, (char *)&hold, sizeof(hold));
	if (options & F_SO_DONTROUTE)
		setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, sizeof(hold));

#ifdef SO_TIMESTAMP
	if (!(options&F_LATENCY)) {
		int on = 1;
		if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
			fprintf(stderr, "Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP\n");
	}
#endif
	if (options & F_MARK) {
		if (setsockopt(icmp_sock, SOL_SOCKET, SO_MARK,
				&mark, sizeof(mark)) == -1) {
			/* we probably dont wanna exit since old kernels
			 * dont support mark ..
			*/
			fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
		}
	}

	/* Set some SNDTIMEO to prevent blocking forever
	 * on sends, when device is too slow or stalls. Just put limit
	 * of one second, or "interval", if it is less.
	 */
	tv.tv_sec = 1;
	tv.tv_usec = 0;
	if (interval < 1000) {
		tv.tv_sec = 0;
		tv.tv_usec = 1000 * SCHINT(interval);
	}
	setsockopt(icmp_sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));

	/* Set RCVTIMEO to "interval". Note, it is just an optimization
	 * allowing to avoid redundant poll(). */
	tv.tv_sec = SCHINT(interval)/1000;
	tv.tv_usec = 1000*(SCHINT(interval)%1000);
	if (setsockopt(icmp_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)))
		options |= F_FLOOD_POLL;

	if (!(options & F_PINGFILLED)) {
		int i;
		u_char *p = outpack+8;

		/* Do not forget about case of small datalen,
		 * fill timestamp area too!
		 */
		for (i = 0; i < datalen; ++i)
			*p++ = i;
	}

	ident = htons(getpid() & 0xFFFF);

	set_signal(SIGINT, sigexit);
	set_signal(SIGALRM, sigexit);
	set_signal(SIGQUIT, sigstatus);

	gettimeofday(&start_time, NULL);

	if (deadline) {
		struct itimerval it;

		it.it_interval.tv_sec = 0;
		it.it_interval.tv_usec = 0;
		it.it_value.tv_sec = deadline;
		it.it_value.tv_usec = 0;
		setitimer(ITIMER_REAL, &it, NULL);
	}

	if (isatty(STDOUT_FILENO)) {
		struct winsize w;

		if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) {
			if (w.ws_col > 0)
				screen_width = w.ws_col;
		}
	}
}
Ejemplo n.º 6
0
Archivo: net.c Proyecto: jmscott/blobio
/*
 *  Do a timed write() of an entire buffer.
 *  Returns
 *
 *	0	=> entire buffer written without error
 *	1	=> write() timed out
 *	-1	=> write() error
 */
int
net_write(int fd, void *buf, size_t buf_size, unsigned timeout)
{
	static char n[] = "net_write";

	int nwrite;
	unsigned char *b, *b_end;
	struct sigaction a;
	struct itimerval t;
	int e;

	b = buf;
	b_end = buf + buf_size;

	/*
	 *  Set the timeout alarm handler.
	 */
	memset(&a, 0, sizeof a);

	alarm_caught = 0;
	a.sa_handler = catch_SIGALRM;
	a.sa_flags = 0;
	sigemptyset(&a.sa_mask);
	t.it_interval.tv_sec = 0;
	t.it_interval.tv_usec = 0;
	t.it_value.tv_sec = timeout;
	t.it_value.tv_usec = 0;
again:
	/*
	 *  Set the ALRM handler.
	 */
	if (sigaction(SIGALRM, &a, (struct sigaction *)0))
		panic3(n, "sigaction(ALRM) failed", strerror(errno));
	/*
	 *  Set the timer
	 */
	if (setitimer(ITIMER_REAL, &t, (struct itimerval *)0))
		panic3(n, "write_buf: setitimer(REAL) failed", strerror(errno));
	nwrite = write(fd, (void *)b, b_end - b);
	e = errno;

	/*
	 *  Disable timer.
	 *
	 *  Note:
	 *	Does setitimer(t.it_interval.tv_sec == 0) above imply
	 *	timer never refires?
	 */
	t.it_value.tv_sec = 0;
	t.it_value.tv_usec = 0;
	if (setitimer(ITIMER_REAL, &t, (struct itimerval *)0))
		panic3(n, "setitimer(REAL, 0) failed", strerror(errno));

	if (nwrite < 0) {
		char tbuf[20];

		if (e != EINTR && e != EAGAIN) {
			error3(n, "write() failed", strerror(errno));
			errno = e;
			return -1;
		}
		if (!alarm_caught)
			goto again;

		alarm_caught = 0;
		snprintf(tbuf, sizeof tbuf, "timed out after %d secs", timeout);
		error3(n, "alarm caught", tbuf);
		return 1;
	}
	b += nwrite;
	if (b < b_end)
		goto again;
	return 0;
}
Ejemplo n.º 7
0
int main(int argc, char **argv)
{
	int sd, rc, n, tmp;
	char msg[MAX_MSG];
	int nfds;
	int send_timestamp = 0;
	int recv_started = 0;
	struct pollfd *pfds;
	struct alsa_dev *dev;
	CELTEncoder *enc_state;
	CELTDecoder *dec_state;
	CELTMode *mode;
	struct sched_param param;
	JitterBuffer *jitter;
	SpeexEchoState *echo_state;
	char mac_own[6], mac_remote[6];

	if (argc != 4)
		panic("Usage %s plughw:0,0 <lmac in xx:xx:xx:xx:xx:xx> <rmac>\n", argv[0]);
 
	register_signal(SIGINT, sighandler);

	hack_mac(mac_own, argv[2], strlen(argv[2]));
	hack_mac(mac_remote, argv[3], strlen(argv[3]));
 
	sd = socket(AF_LANA, SOCK_RAW, 0);
	if (sd < 0)
		panic("%s: cannot open socket \n", argv[0]);

	printf("If ready hit key!\n"); //user must do binding
	getchar();

	dev = alsa_open(argv[1], SAMPLING_RATE, CHANNELS, FRAME_SIZE);

	mode = celt_mode_create(SAMPLING_RATE, FRAME_SIZE, NULL);
	enc_state = celt_encoder_create(mode, CHANNELS, NULL);
	dec_state = celt_decoder_create(mode, CHANNELS, NULL);

	param.sched_priority = sched_get_priority_min(SCHED_FIFO);
	if (sched_setscheduler(0, SCHED_FIFO, &param))
		whine("sched_setscheduler error!\n");
   
	/* Setup all file descriptors for poll()ing */
	nfds = alsa_nfds(dev);
	pfds = xmalloc(sizeof(*pfds) * (nfds + 1));

	alsa_getfds(dev, pfds, nfds);

	pfds[nfds].fd = sd;
	pfds[nfds].events = POLLIN;

	/* Setup jitter buffer using decoder */
	jitter = jitter_buffer_init(FRAME_SIZE);
	tmp = FRAME_SIZE;
	jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MARGIN, &tmp);

	/* Echo canceller with 200 ms tail length */
	echo_state = speex_echo_state_init(FRAME_SIZE, 10 * FRAME_SIZE);
	tmp = SAMPLING_RATE;
	speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);

	register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);

	alsa_start(dev);
	printf("ALSA started!\n");

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = interval;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = interval;
	setitimer(ITIMER_REAL, &itimer, NULL);

	while (!sigint) {
		poll(pfds, nfds + 1, -1);

		/* Received packets */
		if (pfds[nfds].revents & POLLIN) {
			memset(msg, 0, MAX_MSG);
			n = recv(sd, msg, MAX_MSG, 0);
			if (n <= 0)
				goto do_alsa;
			pkts_in++;
			int recv_timestamp;
			memcpy(&recv_timestamp, msg, sizeof(recv_timestamp));
			JitterBufferPacket packet;
			packet.data = msg+4/*+6+6+2*/;
			packet.len = n-4/*-6-6-2*/;
			packet.timestamp = recv_timestamp;
			packet.span = FRAME_SIZE;
			packet.sequence = 0;

			/* Put content of the packet into the jitter buffer,
			   except for the pseudo-header */
			jitter_buffer_put(jitter, &packet);
			recv_started = 1;
		}
do_alsa:
		/* Ready to play a frame (playback) */
		if (alsa_play_ready(dev, pfds, nfds)) {
			short pcm[FRAME_SIZE * CHANNELS] = {0};
			if (recv_started) {
				JitterBufferPacket packet;
				/* Get audio from the jitter buffer */
				packet.data = msg;
				packet.len  = MAX_MSG;
				jitter_buffer_tick(jitter);
				jitter_buffer_get(jitter, &packet, FRAME_SIZE,
						  NULL);
				if (packet.len == 0)
					packet.data=NULL;
				celt_decode(dec_state, (const unsigned char *)
					    packet.data, packet.len, pcm);
			}
			/* Playback the audio and reset the echo canceller
			   if we got an underrun */

			alsa_write(dev, pcm, FRAME_SIZE);
//			if (alsa_write(dev, pcm, FRAME_SIZE)) 
//				speex_echo_state_reset(echo_state);
			/* Put frame into playback buffer */
//			speex_echo_playback(echo_state, pcm);
		}

		/* Audio available from the soundcard (capture) */
		if (alsa_cap_ready(dev, pfds, nfds)) {
			short pcm[FRAME_SIZE * CHANNELS];
			      //pcm2[FRAME_SIZE * CHANNELS];
			char outpacket[MAX_MSG];

			alsa_read(dev, pcm, FRAME_SIZE);
			/* Perform echo cancellation */
//			speex_echo_capture(echo_state, pcm, pcm2);
//			for (i = 0; i < FRAME_SIZE * CHANNELS; ++i)
//				pcm[i] = pcm2[i];

			celt_encode(enc_state, pcm, NULL, (unsigned char *)
				    (outpacket+4+6+6+2), PACKETSIZE);

			/* Pseudo header: four null bytes and a 32-bit
			   timestamp; XXX hack */
			memcpy(outpacket,mac_remote,6);
			memcpy(outpacket+6,mac_own,6);
			outpacket[6+6] = (uint8_t) 0xac;
			outpacket[6+6+1] = (uint8_t) 0xdc;
			memcpy(outpacket+6+6+2, &send_timestamp, sizeof(send_timestamp));
			send_timestamp += FRAME_SIZE;

			rc = sendto(sd, outpacket, PACKETSIZE+4+6+6+2, 0, NULL, 0);
			if (rc < 0)
				panic("cannot send to socket");
			pkts_out++;
		}
	}

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = 0;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itimer, NULL); 

	close(sd);
	return 0;
}
static int
do_test (void)
{
  int result = 0;

  char name[sizeof "/tst-mqueue2-" + sizeof (pid_t) * 3];
  snprintf (name, sizeof (name), "/tst-mqueue2-%u", getpid ());

  struct mq_attr attr = { .mq_maxmsg = 2, .mq_msgsize = 2 };
  mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);

  if (q == (mqd_t) -1)
    {
      printf ("mq_open failed with: %m\n");
      return result;
    }
  else
    add_temp_mq (name);

  mqd_t q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
  if (q2 != (mqd_t) -1)
    {
      puts ("mq_open with O_EXCL unexpectedly succeeded");
      result = 1;
    }
  else if (errno != EEXIST)
    {
      printf ("mq_open did not fail with EEXIST: %m\n");
      result = 1;
    }

  char name2[sizeof "/tst-mqueue2-2-" + sizeof (pid_t) * 3];
  snprintf (name2, sizeof (name2), "/tst-mqueue2-2-%u", getpid ());

  attr.mq_maxmsg = -2;
  q2 = mq_open (name2, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
  if (q2 != (mqd_t) -1)
    {
      puts ("mq_open with invalid mq_maxmsg unexpectedly succeeded");
      add_temp_mq (name2);
      result = 1;
    }
  else if (errno != EINVAL)
    {
      printf ("mq_open with invalid mq_maxmsg did not fail with "
	      "EINVAL: %m\n");
      result = 1;
    }

  attr.mq_maxmsg = 2;
  attr.mq_msgsize = -56;
  q2 = mq_open (name2, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
  if (q2 != (mqd_t) -1)
    {
      puts ("mq_open with invalid mq_msgsize unexpectedly succeeded");
      add_temp_mq (name2);
      result = 1;
    }
  else if (errno != EINVAL)
    {
      printf ("mq_open with invalid mq_msgsize did not fail with "
	      "EINVAL: %m\n");
      result = 1;
    }

  char buf[3];
  struct timespec ts;
  if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
    ts.tv_sec += 10;
  else
    {
      ts.tv_sec = time (NULL) + 10;
      ts.tv_nsec = 0;
    }

  if (mq_timedreceive (q, buf, 1, NULL, &ts) == 0)
    {
      puts ("mq_timedreceive with too small msg_len did not fail");
      result = 1;
    }
  else if (errno != EMSGSIZE)
    {
      printf ("mq_timedreceive with too small msg_len did not fail with "
	      "EMSGSIZE: %m\n");
      result = 1;
    }

  ts.tv_nsec = -1;
  if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
    {
      puts ("mq_timedreceive with negative tv_nsec did not fail");
      result = 1;
    }
  else if (errno != EINVAL)
    {
      printf ("mq_timedreceive with negative tv_nsec did not fail with "
	      "EINVAL: %m\n");
      result = 1;
    }

  ts.tv_nsec = 1000000000;
  if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
    {
      puts ("mq_timedreceive with tv_nsec >= 1000000000 did not fail");
      result = 1;
    }
  else if (errno != EINVAL)
    {
      printf ("mq_timedreceive with tv_nsec >= 1000000000 did not fail with "
	      "EINVAL: %m\n");
      result = 1;
    }

  struct sigaction sa = { .sa_handler = alrm_handler, .sa_flags = 0 };
  sigemptyset (&sa.sa_mask);
  sigaction (SIGALRM, &sa, NULL);

  struct itimerval it = { .it_value = { .tv_sec = 1 } };
  setitimer (ITIMER_REAL, &it, NULL);

  if (mq_receive (q, buf, 2, NULL) == 0)
    {
      puts ("mq_receive on empty queue did not block");
      result = 1;
    }
  else if (errno != EINTR)
    {
      printf ("mq_receive on empty queue did not fail with EINTR: %m\n");
      result = 1;
    }

  setitimer (ITIMER_REAL, &it, NULL);

  ts.tv_nsec = 0;
  if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
    {
      puts ("mq_timedreceive on empty queue did not block");
      result = 1;
    }
  else if (errno != EINTR)
    {
      printf ("mq_timedreceive on empty queue did not fail with EINTR: %m\n");
      result = 1;
    }

  buf[0] = '6';
  buf[1] = '7';
  if (mq_send (q, buf, 2, 3) != 0
      || (buf[0] = '8', mq_send (q, buf, 1, 4) != 0))
    {
      printf ("mq_send failed: %m\n");
      result = 1;
    }

  memset (buf, ' ', sizeof (buf));

  unsigned int prio;
  ssize_t rets = mq_receive (q, buf, 3, &prio);
  if (rets != 1)
    {
      if (rets == -1)
	printf ("mq_receive failed: %m\n");
      else
	printf ("mq_receive returned %zd != 1\n", rets);
      result = 1;
    }
  else if (prio != 4 || memcmp (buf, "8  ", 3) != 0)
    {
      printf ("mq_receive prio %u (4) buf \"%c%c%c\" (\"8  \")\n",
	      prio, buf[0], buf[1], buf[2]);
      result = 1;
    }

  rets = mq_receive (q, buf, 2, NULL);
  if (rets != 2)
    {
      if (rets == -1)
	printf ("mq_receive failed: %m\n");
      else
	printf ("mq_receive returned %zd != 2\n", rets);
      result = 1;
    }
  else if (memcmp (buf, "67 ", 3) != 0)
    {
      printf ("mq_receive buf \"%c%c%c\" != \"67 \"\n",
	      buf[0], buf[1], buf[2]);
      result = 1;
    }

  buf[0] = '2';
  buf[1] = '1';
  if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
    ts.tv_sec = time (NULL);
  ts.tv_nsec = -1000000001;
  if ((mq_timedsend (q, buf, 2, 5, &ts) != 0
       && (errno != EINVAL || mq_send (q, buf, 2, 5) != 0))
      || (buf[0] = '3', ts.tv_nsec = -ts.tv_nsec,
	  (mq_timedsend (q, buf, 1, 4, &ts) != 0
	   && (errno != EINVAL || mq_send (q, buf, 1, 4) != 0))))
    {
      printf ("mq_timedsend failed: %m\n");
      result = 1;
    }

  buf[0] = '-';
  ts.tv_nsec = 1000000001;
  if (mq_timedsend (q, buf, 1, 6, &ts) == 0)
    {
      puts ("mq_timedsend with tv_nsec >= 1000000000 did not fail");
      result = 1;
    }
  else if (errno != EINVAL)
    {
      printf ("mq_timedsend with tv_nsec >= 1000000000 did not fail with "
	      "EINVAL: %m\n");
      result = 1;
    }

  ts.tv_nsec = -2;
  if (mq_timedsend (q, buf, 1, 6, &ts) == 0)
    {
      puts ("mq_timedsend with negative tv_nsec did not fail");
      result = 1;
    }
  else if (errno != EINVAL)
    {
      printf ("mq_timedsend with megatove tv_nsec did not fail with "
	      "EINVAL: %m\n");
      result = 1;
    }

  setitimer (ITIMER_REAL, &it, NULL);

  if (mq_send (q, buf, 2, 8) == 0)
    {
      puts ("mq_send on full queue did not block");
      result = 1;
    }
  else if (errno != EINTR)
    {
      printf ("mq_send on full queue did not fail with EINTR: %m\n");
      result = 1;
    }

  setitimer (ITIMER_REAL, &it, NULL);

  ts.tv_sec += 10;
  ts.tv_nsec = 0;
  if (mq_timedsend (q, buf, 2, 7, &ts) == 0)
    {
      puts ("mq_timedsend on full queue did not block");
      result = 1;
    }
  else if (errno != EINTR)
    {
      printf ("mq_timedsend on full queue did not fail with EINTR: %m\n");
      result = 1;
    }

  memset (buf, ' ', sizeof (buf));

  if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
    ts.tv_sec = time (NULL);
  ts.tv_nsec = -1000000001;
  rets = mq_timedreceive (q, buf, 2, &prio, &ts);
  if (rets == -1 && errno == EINVAL)
    rets = mq_receive (q, buf, 2, &prio);
  if (rets != 2)
    {
      if (rets == -1)
	printf ("mq_timedreceive failed: %m\n");
      else
	printf ("mq_timedreceive returned %zd != 2\n", rets);
      result = 1;
    }
  else if (prio != 5 || memcmp (buf, "21 ", 3) != 0)
    {
      printf ("mq_timedreceive prio %u (5) buf \"%c%c%c\" (\"21 \")\n",
	      prio, buf[0], buf[1], buf[2]);
      result = 1;
    }

  if (mq_receive (q, buf, 1, NULL) == 0)
    {
      puts ("mq_receive with too small msg_len did not fail");
      result = 1;
    }
  else if (errno != EMSGSIZE)
    {
      printf ("mq_receive with too small msg_len did not fail with "
	      "EMSGSIZE: %m\n");
      result = 1;
    }

  ts.tv_nsec = -ts.tv_nsec;
  rets = mq_timedreceive (q, buf, 2, NULL, &ts);
  if (rets == -1 && errno == EINVAL)
    rets = mq_receive (q, buf, 2, NULL);
  if (rets != 1)
    {
      if (rets == -1)
	printf ("mq_timedreceive failed: %m\n");
      else
	printf ("mq_timedreceive returned %zd != 1\n", rets);
      result = 1;
    }
  else if (memcmp (buf, "31 ", 3) != 0)
    {
      printf ("mq_timedreceive buf \"%c%c%c\" != \"31 \"\n",
	      buf[0], buf[1], buf[2]);
      result = 1;
    }

  if (mq_send (q, "", 0, 2) != 0)
    {
      printf ("mq_send with msg_len 0 failed: %m\n");
      result = 1;
    }

  rets = mq_receive (q, buf, 2, &prio);
  if (rets)
    {
      if (rets == -1)
	printf ("mq_receive failed: %m\n");
      else
	printf ("mq_receive returned %zd != 0\n", rets);
      result = 1;
    }

  long mq_prio_max = sysconf (_SC_MQ_PRIO_MAX);
  if (mq_prio_max > 0 && (unsigned int) mq_prio_max == mq_prio_max)
    {
      if (mq_send (q, buf, 1, mq_prio_max) == 0)
	{
	  puts ("mq_send with MQ_PRIO_MAX priority unpexpectedly succeeded");
	  result = 1;
	}
      else if (errno != EINVAL)
	{
	  printf ("mq_send with MQ_PRIO_MAX priority did not fail with "
		  "EINVAL: %m\n");
	  result = 1;
	}

      if (mq_send (q, buf, 1, mq_prio_max - 1) != 0)
	{
	  printf ("mq_send with MQ_PRIO_MAX-1 priority failed: %m\n");
	  result = 1;
	}
    }

  if (mq_unlink (name) != 0)
    {
      printf ("mq_unlink failed: %m\n");
      result = 1;
    }

  q2 = mq_open (name, O_RDWR);
  if (q2 != (mqd_t) -1)
    {
      printf ("mq_open of unlinked %s without O_CREAT unexpectedly"
	      "succeeded\n", name);
      result = 1;
    }
  else if (errno != ENOENT)
    {
      printf ("mq_open of unlinked %s without O_CREAT did not fail with "
	      "ENOENT: %m\n", name);
      result = 1;
    }

  if (mq_close (q) != 0)
    {
      printf ("mq_close in parent failed: %m\n");
      result = 1;
    }

  if (mq_receive (q, buf, 2, NULL) == 0)
    {
      puts ("mq_receive on invalid mqd_t did not fail");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_receive on invalid mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  if (mq_send (q, buf, 1, 2) == 0)
    {
      puts ("mq_send on invalid mqd_t did not fail");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_send on invalid mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  if (mq_getattr (q, &attr) == 0)
    {
      puts ("mq_getattr on invalid mqd_t did not fail");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_getattr on invalid mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  memset (&attr, 0, sizeof (attr));
  if (mq_setattr (q, &attr, NULL) == 0)
    {
      puts ("mq_setattr on invalid mqd_t did not fail");
      result = 1;
    }
  else if (errno != EBADF)
    {
      printf ("mq_setattr on invalid mqd_t did not fail with EBADF: %m\n");
      result = 1;
    }

  if (mq_unlink ("/tst-mqueue2-which-should-never-exist") != -1)
    {
      puts ("mq_unlink of non-existant message queue unexpectedly succeeded");
      result = 1;
    }
  else if (errno != ENOENT)
    {
      printf ("mq_unlink of non-existant message queue did not fail with "
	      "ENOENT: %m\n");
      result = 1;
    }
  return result;
}
Ejemplo n.º 9
0
static void
mpx_handler( int signal )
{
	int retval;
	MasterEvent *mev, *head;
	Threadlist *me = NULL;
#ifdef REGENERATE
	int lastthread;
#endif
#ifdef MPX_DEBUG_OVERHEAD
	long long usec;
	int didwork = 0;
	usec = PAPI_get_real_usec(  );
#endif
#ifdef MPX_DEBUG_TIMER
	long long thiscall;
#endif

	signal = signal;		 /* unused */

	MPXDBG( "Handler in thread\n" );

	/* This handler can be invoked either when a timer expires
	 * or when another thread in this handler responding to the
	 * timer signals other threads.  We have to distinguish
	 * these two cases so that we don't get infinite loop of 
	 * handler calls.  To do that, we look at the value of
	 * threads_responding.  We assume that only one thread can
	 * be active in this signal handler at a time, since the
	 * invoking signal is blocked while the handler is active.
	 * If threads_responding == 0, the current thread caught
	 * the original timer signal.  (This thread may not have
	 * any active event lists itself, though.)  This first
	 * thread sends a signal to each of the other threads in
	 * our list of threads that have master events lists.  If
	 * threads_responding != 0, then this thread was signaled
	 * by another thread.  We decrement that value and look
	 * for an active events.  threads_responding should
	 * reach zero when all active threads have handled their
	 * signal.  It's probably possible for a thread to die
	 * before it responds to a signal; if that happens,
	 * threads_responding won't reach zero until the next
	 * timer signal happens.  Then the signalled thread won't
	 * signal any other threads.  If that happens only
	 * occasionally, there should be no harm.  Likewise if
	 * a new thread is added that fails to get signalled.
	 * As for locking, we have to lock this list to prevent
	 * another thread from modifying it, but if *this* thread
	 * is trying to update the list (from another function) and
	 * is signaled while it holds the lock, we will have deadlock.
	 * Therefore, noninterrupt functions that update *this* list
	 * must disable the signal that invokes this handler.
	 */

#ifdef PTHREADS
	_papi_hwi_lock( MULTIPLEX_LOCK );

	if ( threads_responding == 0 ) {	/* this thread caught the timer sig */
		/* Signal the other threads with event lists */
#ifdef MPX_DEBUG_TIMER
		thiscall = _papi_hwd_get_real_usec(  );
		MPXDBG( "last signal was %lld usec ago\n", thiscall - lastcall );
		lastcall = thiscall;
#endif
		MPXDBG( "%#x caught it, tlist is %p\n", self, tlist );
		for ( t = tlist; t != NULL; t = t->next ) {
			if ( pthread_equal( t->thr, self ) == 0 ) {
				++threads_responding;
				retval = pthread_kill( t->thr, _papi_os_info.itimer_sig );
				assert( retval == 0 );
#ifdef MPX_DEBUG_SIGNALS
				MPXDBG( "%#x signaling %#x\n", self, t->thr );
#endif
			}
		}
	} else {
#ifdef MPX_DEBUG_SIGNALS
		MPXDBG( "%#x was tapped, tr = %d\n", self, threads_responding );
#endif
		--threads_responding;
	}
#ifdef REGENERATE
	lastthread = ( threads_responding == 0 );
#endif
	_papi_hwi_unlock( MULTIPLEX_LOCK );
#endif

	/* See if this thread has an active event list */
	head = get_my_threads_master_event_list(  );
	if ( head != NULL ) {

		/* Get the thread header for this master event set.  It's
		 * always in the first record of the set (and maybe in others)
		 * if any record in the set is active.
		 */
		me = head->mythr;

		/* Find the event that's currently active, stop and read
		 * it, then start the next event in the list.
		 * No need to lock the list because other functions
		 * disable the timer interrupt before they update the list.
		 */
		if ( me != NULL && me->cur_event != NULL ) {
			long long counts[2];
			MasterEvent *cur_event = me->cur_event;
			long long cycles = 0, total_cycles = 0;

			retval = PAPI_stop( cur_event->papi_event, counts );
			MPXDBG( "retval=%d, cur_event=%p, I'm tid=%lx\n",
					retval, cur_event, me->tid );

			if ( retval == PAPI_OK ) {
				MPXDBG( "counts[0] = %lld counts[1] = %lld\n", counts[0],
						counts[1] );

				cur_event->count += counts[0];
				cycles = ( cur_event->pi.event_type == SCALE_EVENT )
					? counts[0] : counts[1];

				me->total_c += cycles;
				total_cycles = me->total_c - cur_event->prev_total_c;
				cur_event->prev_total_c = me->total_c;

				/* If it's a rate, count occurrences & average later */
				if ( !cur_event->is_a_rate ) {
					cur_event->cycles += cycles;
					if ( cycles >= MPX_MINCYC ) {	/* Only update current rate on a decent slice */
						cur_event->rate_estimate =
							( double ) counts[0] / ( double ) cycles;
					}
					cur_event->count_estimate +=
						( long long ) ( ( double ) total_cycles *
										cur_event->rate_estimate );
                                        MPXDBG("New estimate = %lld (%lld cycles * %lf rate)\n",
                                               cur_event->count_estimate,total_cycles,
                                               cur_event->rate_estimate);
				} else {
					/* Make sure we ran long enough to get a useful measurement (otherwise
					 * potentially inaccurate rate measurements get averaged in with
					 * the same weight as longer, more accurate ones.)
					 */
					if ( cycles >= MPX_MINCYC ) {
						cur_event->cycles += 1;
					} else {
						cur_event->count -= counts[0];
					}
				}
			} else {
				MPXDBG( "%lx retval = %d, skipping\n", me->tid, retval );
				MPXDBG( "%lx value = %lld cycles = %lld\n\n",
						me->tid, cur_event->count, cur_event->cycles );
			}

			MPXDBG
				( "tid(%lx): value = %lld (%lld) cycles = %lld (%lld) rate = %lf\n\n",
				  me->tid, cur_event->count, cur_event->count_estimate,
				  cur_event->cycles, total_cycles, cur_event->rate_estimate );
			/* Start running the next event; look for the
			 * next one in the list that's marked active.
			 * It's possible that this event is the only
			 * one active; if so, we should restart it,
			 * but only after considerating all the other
			 * possible events.
			 */
			if ( ( retval != PAPI_OK ) ||
				 ( ( retval == PAPI_OK ) && ( cycles >= MPX_MINCYC ) ) ) {
				for ( mev =
					  ( cur_event->next == NULL ) ? head : cur_event->next;
					  mev != cur_event;
					  mev = ( mev->next == NULL ) ? head : mev->next ) {
					/* Found the next one to start */
					if ( mev->active ) {
						me->cur_event = mev;
						break;
					}
				}
			}

			if ( me->cur_event->active ) {
				retval = PAPI_start( me->cur_event->papi_event );
			}
#ifdef MPX_DEBUG_OVERHEAD
			didwork = 1;
#endif
		}
	}
#ifdef ANY_THREAD_GETS_SIGNAL
	else {
		Threadlist *t;
		for ( t = tlist; t != NULL; t = t->next ) {
			if ( ( t->tid == _papi_hwi_thread_id_fn(  ) ) ||
				 ( t->head == NULL ) )
				continue;
			MPXDBG( "forwarding signal to thread %lx\n", t->tid );
			retval = ( *_papi_hwi_thread_kill_fn ) ( t->tid, _papi_os_info.itimer_sig );
			if ( retval != 0 ) {
				MPXDBG( "forwarding signal to thread %lx returned %d\n",
						t->tid, retval );
			}
		}
	}
#endif

#ifdef REGENERATE
	/* Regenerating the signal each time through has the
	 * disadvantage that if any thread ever drops a signal,
	 * the whole time slicing system will stop.  Using
	 * an automatically regenerated signal may have the
	 * disadvantage that a new signal can arrive very
	 * soon after all the threads have finished handling
	 * the last one, so the interval may be too small for
	 * accurate data collection.  However, using the
	 * MIN_CYCLES check above should alleviate this.
	 */
	/* Reset the timer once all threads have responded */
	if ( lastthread ) {
		retval = setitimer( _papi_os_info.itimer_num, &itime, NULL );
		assert( retval == 0 );
#ifdef MPX_DEBUG_TIMER
		MPXDBG( "timer restarted by %lx\n", me->tid );
#endif
	}
#endif

#ifdef MPX_DEBUG_OVERHEAD
	usec = _papi_hwd_get_real_usec(  ) - usec;
	MPXDBG( "handler %#x did %swork in %lld usec\n",
			self, ( didwork ? "" : "no " ), usec );
#endif
}
Ejemplo n.º 10
0
int main(void)
{
	struct itimerval it;
	struct tms buf;
	clock_t clk_tck, start_real, start_virtual, end_real, end_virtual;
	unsigned long count;
	void *data;
	int size;
	char *setting1, *setting2;
	int i;
#ifdef TEST_THREADS
	pthread_t t[TEST_THREADS];
	void *t_retval;
#endif

	data = NULL;
	size = 0x12345678;

	for (i = 0; tests[i][0]; i++) {
		const char *hash = tests[i][0];
		const char *key = tests[i][1];
		const char *setting = tests[i][2];
		const char *p;
		int ok = !setting || strlen(hash) >= 30;
		int o_size;
		char s_buf[30], o_buf[61];
		if (!setting) {
			memcpy(s_buf, hash, sizeof(s_buf) - 1);
			s_buf[sizeof(s_buf) - 1] = 0;
			setting = s_buf;
		}

		__set_errno(0);
		p = crypt(key, setting);
		if ((!ok && !errno) || strcmp(p, hash)) {
			printf("FAILED (crypt/%d)\n", i);
			return 1;
		}

		if (ok && strcmp(crypt(key, hash), hash)) {
			printf("FAILED (crypt/%d)\n", i);
			return 1;
		}

		for (o_size = -1; o_size <= (int)sizeof(o_buf); o_size++) {
			int ok_n = ok && o_size == (int)sizeof(o_buf);
			const char *x = "abc";
			strcpy(o_buf, x);
			if (o_size >= 3) {
				x = "*0";
				if (setting[0] == '*' && setting[1] == '0')
					x = "*1";
			}
			__set_errno(0);
			p = crypt_rn(key, setting, o_buf, o_size);
			if ((ok_n && (!p || strcmp(p, hash))) ||
			    (!ok_n && (!errno || p || strcmp(o_buf, x)))) {
				printf("FAILED (crypt_rn/%d)\n", i);
				return 1;
			}
		}

		__set_errno(0);
		p = crypt_ra(key, setting, &data, &size);
		if ((ok && (!p || strcmp(p, hash))) ||
		    (!ok && (!errno || p || strcmp((char *)data, hash)))) {
			printf("FAILED (crypt_ra/%d)\n", i);
			return 1;
		}
	}

	setting1 = crypt_gensalt(which[0], 12, data, size);
	if (!setting1 || strncmp(setting1, "$2a$12$", 7)) {
		puts("FAILED (crypt_gensalt)\n");
		return 1;
	}

	setting2 = crypt_gensalt_ra(setting1, 12, data, size);
	if (strcmp(setting1, setting2)) {
		puts("FAILED (crypt_gensalt_ra/1)\n");
		return 1;
	}

	(*(char *)data)++;
	setting1 = crypt_gensalt_ra(setting2, 12, data, size);
	if (!strcmp(setting1, setting2)) {
		puts("FAILED (crypt_gensalt_ra/2)\n");
		return 1;
	}

	free(setting1);
	free(setting2);
	free(data);

#if defined(_SC_CLK_TCK) || !defined(CLK_TCK)
	clk_tck = sysconf(_SC_CLK_TCK);
#else
	clk_tck = CLK_TCK;
#endif

	running = 1;
	signal(SIGALRM, handle_timer);

	memset(&it, 0, sizeof(it));
	it.it_value.tv_sec = 5;
	setitimer(ITIMER_REAL, &it, NULL);

	start_real = times(&buf);
	start_virtual = buf.tms_utime + buf.tms_stime;

	count = (char *)run((char *)0) - (char *)0;

	end_real = times(&buf);
	end_virtual = buf.tms_utime + buf.tms_stime;
	if (end_virtual == start_virtual) end_virtual++;

	printf("%.1f c/s real, %.1f c/s virtual\n",
		(float)count * clk_tck / (end_real - start_real),
		(float)count * clk_tck / (end_virtual - start_virtual));

#ifdef TEST_THREADS
	running = 1;
	it.it_value.tv_sec = 60;
	setitimer(ITIMER_REAL, &it, NULL);
	start_real = times(&buf);

	for (i = 0; i < TEST_THREADS; i++)
	if (pthread_create(&t[i], NULL, run, i + (char *)0)) {
		perror("pthread_create");
		return 1;
	}

	for (i = 0; i < TEST_THREADS; i++) {
		if (pthread_join(t[i], &t_retval)) {
			perror("pthread_join");
			continue;
		}
		if (!t_retval) continue;
		count = (char *)t_retval - (char *)0;
		end_real = times(&buf);
		printf("%d: %.1f c/s real\n", i,
			(float)count * clk_tck / (end_real - start_real));
	}
#endif

	return 0;
}
Ejemplo n.º 11
0
void ftp_master_process_cycle()
{
    int fd = open("/dev/zero",O_RDWR,0);
    mptr = mmap(0,sizeof(pthread_mutex_t),PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
    close(fd);

    ftp_process_identity = FTP_MASTER_PROCESS;

    pthread_mutexattr_t mattr;
    pthread_mutexattr_init(&mattr);
    pthread_mutexattr_setpshared(&mattr,PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(mptr,&mattr);

	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set,SIGCHLD);
	sigaddset(&set,SIGINT);
	sigaddset(&set,SIGTERM);
	sigaddset(&set,SIGALRM);
	if(sigprocmask(SIG_SETMASK,&set,NULL) == 1){
		err_quit("ftp_master_process_cycle - sigprocmask");
	}

    int i;
    for(i = 0;i < max_connections;i++)
        ftp_respawn_work_process(i);

    close(ftp_listenfd);

    sigemptyset(&set);

    unsigned delay = 0;
	while(1) {
		sigsuspend(&set);
		if(ftp_sigchld) {
            ftp_sigchld = 0;
            int alive = 0 ;
            for(i = 0;i < max_connections;i++) {
                if(ftp_process[i].pid == -1 && !ftp_process[i].exited) {
                    ftp_respawn_work_process(i);
                }
                if(ftp_process[i].pid)  alive = 1;
            }
            if(!alive && (ftp_terminate || ftp_quit))   exit(0);
		}

        if(ftp_terminate) {
            if(delay == 0) {
                delay = 2000;
                struct itimerval t;
                t.it_interval.tv_sec = 0;
                t.it_interval.tv_usec = 0;
                t.it_value.tv_sec = delay / 1000;
                t.it_value.tv_usec = delay % 1000 * 1000;
                setitimer(ITIMER_REAL,&t,NULL);
            }
            ftp_signal_work_process(SIGTERM);
        }

        if(ftp_sigalrm) {
            ftp_signal_work_process(SIGKILL);
        }

	}

}
Ejemplo n.º 12
0
void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
    char              *title;
    u_char            *p;
    size_t             size;
    ngx_int_t          i;
    ngx_uint_t         n, sigio;
    sigset_t           set;
    struct itimerval   itv;
    ngx_uint_t         live;
    ngx_msec_t         delay;
    ngx_listening_t   *ls;
    ngx_core_conf_t   *ccf;

    //屏蔽一系列信号,防止被打扰
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigaddset(&set, SIGALRM);
    sigaddset(&set, SIGIO);
    sigaddset(&set, SIGINT);
    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));

    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

    sigemptyset(&set);


    // master_process 静态数组。参考本页
    size = sizeof(master_process);

    for (i = 0; i < ngx_argc; i++) {
        size += ngx_strlen(ngx_argv[i]) + 1;
    }

    title = ngx_pnalloc(cycle->pool, size);

    p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
    for (i = 0; i < ngx_argc; i++) {
        *p++ = ' ';
        p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
    }

    ngx_setproctitle(title);

    //master进程获取core模块配置,ccf中有要创建多少个worker的设定
    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    //启动worker,这时已经有了worker进程
    // NGX_PROCESS_RESPAWN 表示重新生成子进程
    ngx_start_worker_processes(cycle, ccf->worker_processes,            
                               NGX_PROCESS_RESPAWN);
    ngx_start_cache_manager_processes(cycle, 0);  //创建有关cache的子进程

    ngx_new_binary = 0;
    delay = 0;
    sigio = 0;
    live = 1;

    for ( ;; ) {
        //delay用来等待子进程退出的时间,由于我们接受到SIGINT信号后,我们需要先发送信号给子进程,
        //而子进程的退出需要一定的时间,超时时如果子进程已退出,我们父进程就直接退出,
        //否则发送sigkill信号给子进程(强制退出),然后再退出。  
        if (delay) {
            if (ngx_sigalrm) {
                sigio = 0;
                delay *= 2;
                ngx_sigalrm = 0;
            }

            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "termination cycle: %d", 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);  //调用这个将master进程挂起来

        ngx_time_update();

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                       "wake up, sigio %i", sigio);
        
        //ngx_reap为1,说明有子进程已经退出
        if (ngx_reap) {
            ngx_reap = 0;
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");

            //这个里面处理退出的子进程(有的worker异常退出,这时我们就需要重启这个worker ),如果所有子进程都退出则会返回0.  
            live = ngx_reap_children(cycle);
        }

        //如果没有存活的子进程,并且收到了ngx_terminate或者ngx_quit信号,则master退出。 
        if (!live && (ngx_terminate || ngx_quit)) {
            ngx_master_process_exit(cycle);
        }
    
        //收到了sigint信号
        if (ngx_terminate) {
            //设置延时
            if (delay == 0) {
                delay = 50;
            }

            if (sigio) {
                sigio--;
                continue;
            }

            sigio = ccf->worker_processes + 2 /* cache processes */;

            if (delay > 1000) {
                //如果超时,则强制杀死worker 
                ngx_signal_worker_processes(cycle, SIGKILL);
            } else {
                //负责发送sigint给worker,让它退出
                ngx_signal_worker_processes(cycle,
                                       ngx_signal_value(NGX_TERMINATE_SIGNAL));
            }

            continue;
        }

        //收到quit信号
        if (ngx_quit) {
            //发送给worker quit信号
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));

            ls = cycle->listening.elts;
            for (n = 0; n < cycle->listening.nelts; n++) {
                if (ngx_close_socket(ls[n].fd) == -1) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                                  ngx_close_socket_n " %V failed",
                                  &ls[n].addr_text);
                }
            }
            cycle->listening.nelts = 0;

            continue;
        }

        //收到需要reconfig的信号 
        if (ngx_reconfigure) {
            ngx_reconfigure = 0;

            //判断是否热代码替换后的新的代码还在运行中(也就是还没退出当前的master)。如果还在运行中,则不需要重新初始化config
            if (ngx_new_binary) {
                ngx_start_worker_processes(cycle, ccf->worker_processes,
                                           NGX_PROCESS_RESPAWN);
                ngx_start_cache_manager_processes(cycle, 0);
                ngx_noaccepting = 0;

                continue;
            }

            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
            
            //重新初始化config,并重新启动新的worker
            cycle = ngx_init_cycle(cycle);
            if (cycle == NULL) {
                cycle = (ngx_cycle_t *) ngx_cycle;
                continue;
            }

            ngx_cycle = cycle;
            ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
                                                   ngx_core_module);
            ngx_start_worker_processes(cycle, ccf->worker_processes,
                                       NGX_PROCESS_JUST_RESPAWN);
            ngx_start_cache_manager_processes(cycle, 1);
            live = 1;
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
        }

        if (ngx_restart) {
            ngx_restart = 0;
            ngx_start_worker_processes(cycle, ccf->worker_processes,
                                       NGX_PROCESS_RESPAWN);
            ngx_start_cache_manager_processes(cycle, 0);
            live = 1;
        }

        //重新打开
        if (ngx_reopen) {
            ngx_reopen = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
            ngx_reopen_files(cycle, ccf->user);
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_REOPEN_SIGNAL));
        }

        //热代码替换
        if (ngx_change_binary) {
            ngx_change_binary = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
            //进行热代码替换,这里是调用execve来执行新的代码
            ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
        }

        //接受到停止accept连接,其实也就是worker退出(有区别的是,这里master不需要退出)
        if (ngx_noaccept) {
            ngx_noaccept = 0;
            ngx_noaccepting = 1;
            //给worker发送信号
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
        }
    }
}
Ejemplo n.º 13
0
int
set_rotation_timer()
{
#if 0
    double secs_left = 0.0L;
#endif
    struct itimerval itimer = {};
    struct sigaction sa = {
        .sa_sigaction = handler_alarm,
        .sa_flags = SA_RESTART | SA_SIGINFO,
    };
    sigemptyset(&sa.sa_mask);
    sigaction(SIGALRM, &sa, NULL);

#if 0
    secs_left = get_seconds_left_in_today();
    az_log(LOG_DEBUG, "secs_left = %lf", secs_left);

    itimer.it_interval.tv_sec = secs_left;
#else
    itimer.it_interval.tv_sec = 1;
#endif
    itimer.it_interval.tv_usec = 0;
    itimer.it_value = itimer.it_interval;
    assert(setitimer(ITIMER_REAL, &itimer, 0) == 0);

    return 0;
}

int
do_rotate(sc_aggregator_connection_ref conn)
{
    sc_config_pattern_entry *pe;
    struct tm tm;
    time_t t;
    sc_follow_context* cxt = NULL;
    int not_found;
    az_list *li, *lp;

    time(&t);
    localtime_r(&t, &tm);
    for (lp = g_config_patterns; lp; lp = lp->next) {
        pe = (sc_config_pattern_entry*)lp->object;
        char fn[PATH_MAX], dn[PATH_MAX];

        if (pe->rotate && strchr(pe->path, '%')) {
	    strftime(fn, sizeof(fn), pe->path, &tm);
	} else {
	    strncpy(fn, pe->path, sizeof(fn));
	}

	if (pe->displayName) {
	    if (pe->rotate && strchr(pe->displayName, '%')) {
	        strftime(dn, sizeof(dn), pe->displayName, &tm);
	    } else {
	        strncpy(dn, pe->displayName, sizeof(dn));
	    }
	} else {
	    strcpy(dn, basename(fn));
	}
        az_log(LOG_DEBUG, "fname = [%s] / dispname = [%s]", fn, dn);

        not_found = 1;
        for (li = g_context_list; not_found && li; li = li->next) {
            cxt = li->object;
            if (cxt->filename && strcmp(cxt->filename, fn) == 0) {
		if (strcmp(cxt->displayName, dn) == 0) {
                    // , I'm already following it.
                    not_found = 0;
		} else {
		    // displayName has rotated.
		    sc_follow_context_close(cxt);
		}
                az_log(LOG_DEBUG, "=== already following now.", fn, dn);
                break;
            }
        }

        if (not_found) {
            cxt = sc_follow_context_new(fn, dn, pe->append_timestamp, BUFSIZE, conn);
            g_context_list = az_list_add(g_context_list, cxt);
            az_log(LOG_DEBUG, "added: new follow_context");
        }
    }

#if 0
    for (li = g_controller_list; li; li = li->next) {
        char dn[PATH_MAX];
        sc_controller* contr = li->object;

        if (contr->displayName == NULL) {
            continue;
        }

        if (strchr(contr->displayName, '%')) {
	    strftime(dn, sizeof(dn), contr->displayName, &tm);
        } else {
            strncpy(dn, contr->displayName, sizeof(dn));
        }

        not_found = 1;
        for (lj = g_context_list; not_found && lj; lj = lj->next) {
            cxt = lj->object;
            if (cxt->_fd == contr->socket_fd) {
                if (strcmp(cxt->displayName, dn) == 0) {
                    not_found = 0;
                } else {
                    sc_follow_context_close(cxt);
                }
            }
        }

        if (not_found) {
            cxt = sc_follow_context_new_with_fd(contr->socket_fd, dn, 1, BUFSIZE, conn);
            g_context_list = az_list_add(g_context_list, cxt);
            az_log(LOG_DEBUG, "added: new follow_context => displayName: %s", dn);
        }
    }
#endif
    return 0;
}
Ejemplo n.º 14
0
static void xmit_slowpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_num)
{
	int ret, icmp_sock = -1;
	unsigned long num = 1, i = 0;
	struct timeval start, end, diff;
	unsigned long long tx_bytes = 0, tx_packets = 0;
	struct packet_dyn *pktd;
	struct sockaddr_ll saddr = {
		.sll_family = PF_PACKET,
		.sll_halen = ETH_ALEN,
		.sll_ifindex = device_ifindex(ctx->device),
	};

	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	if (ctx->smoke_test)
		icmp_sock = xmit_smoke_setup(ctx);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0 && num > 0 && plen > 0)) {
		pktd = &packet_dyn[i];
		if (pktd->clen + pktd->rlen + pktd->slen) {
			apply_counter(i);
			apply_randomizer(i);
			apply_csum16(i);
		}
retry:
		ret = sendto(sock, packets[i].payload, packets[i].len, 0,
			     (struct sockaddr *) &saddr, sizeof(saddr));
		if (unlikely(ret < 0)) {
			if (errno == ENOBUFS) {
				sched_yield();
				goto retry;
			}
			if (ctx->smoke_test)
				panic("Sendto error: %s!\n", strerror(errno));
		}

		tx_bytes += packets[i].len;
		tx_packets++;

		if (ctx->smoke_test) {
			ret = xmit_smoke_probe(icmp_sock, ctx);
			if (unlikely(ret < 0)) {
				printf("%sSmoke test alert:%s\n", colorize_start(bold), colorize_end());
				printf("  Remote host seems to be unresponsive to ICMP probes!\n");
				printf("  Last instance was packet%lu, seed:%u, trafgen snippet:\n\n",
				       i, seed);

				dump_trafgen_snippet(packets[i].payload, packets[i].len);
				break;
			}
		}

		if (!ctx->rand) {
			i++;
			if (i >= plen)
				i = 0;
		} else
			i = rand() % plen;

		if (ctx->num > 0)
			num--;

		if ((ctx->gap.tv_sec | ctx->gap.tv_nsec) > 0)
			nanosleep(&ctx->gap, NULL);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (ctx->smoke_test)
		close(icmp_sock);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}

static void xmit_fastpath_or_die(struct ctx *ctx, int cpu, unsigned long orig_num)
{
	int ifindex = device_ifindex(ctx->device);
	uint8_t *out = NULL;
	unsigned int it = 0;
	unsigned long num = 1, i = 0, size;
	struct ring tx_ring;
	struct frame_map *hdr;
	struct timeval start, end, diff;
	struct packet_dyn *pktd;
	unsigned long long tx_bytes = 0, tx_packets = 0;

	fmemset(&tx_ring, 0, sizeof(tx_ring));

	size = ring_size(ctx->device, ctx->reserve_size);

	set_sock_prio(sock, 512);
	set_packet_loss_discard(sock);

	setup_tx_ring_layout(sock, &tx_ring, size, ctx->jumbo_support);
	create_tx_ring(sock, &tx_ring, ctx->verbose);
	mmap_tx_ring(sock, &tx_ring);
	alloc_tx_ring_frames(sock, &tx_ring);
	bind_tx_ring(sock, &tx_ring, ifindex);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (ctx->kpull)
		interval = ctx->kpull;
	if (ctx->num > 0)
		num = ctx->num;
	if (ctx->num == 0 && orig_num > 0)
		num = 0;

	set_itimer_interval_value(&itimer, 0, interval);
	setitimer(ITIMER_REAL, &itimer, NULL); 

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0 && num > 0 && plen > 0)) {
		if (!user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
			sched_yield();
			continue;
		}

		hdr = tx_ring.frames[it].iov_base;
		out = ((uint8_t *) hdr) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);

		hdr->tp_h.tp_snaplen = packets[i].len;
		hdr->tp_h.tp_len = packets[i].len;

		pktd = &packet_dyn[i];
		if (pktd->clen + pktd->rlen + pktd->slen) {
			apply_counter(i);
			apply_randomizer(i);
			apply_csum16(i);
		}

		fmemcpy(out, packets[i].payload, packets[i].len);

		tx_bytes += packets[i].len;
		tx_packets++;

		if (!ctx->rand) {
			i++;
			if (i >= plen)
				i = 0;
		} else
			i = rand() % plen;

		kernel_may_pull_from_tx(&hdr->tp_h);

		it++;
		if (it >= tx_ring.layout.tp_frame_nr)
			it = 0;

		if (ctx->num > 0)
			num--;
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	timer_purge();

	destroy_tx_ring(sock, &tx_ring);

	stats[cpu].tx_packets = tx_packets;
	stats[cpu].tx_bytes = tx_bytes;
	stats[cpu].tv_sec = diff.tv_sec;
	stats[cpu].tv_usec = diff.tv_usec;

	stats[cpu].state |= CPU_STATS_STATE_RES;
}
Ejemplo n.º 15
0
/*
 * init_timer - initialize the timer data structures
 */
void
init_timer(void)
{
	/*
	 * Initialize...
	 */
	alarm_flag = 0;
	alarm_overflow = 0;
	adjust_timer = 1;
	stats_timer = 0;
	huffpuff_timer = 0;
	interface_timer = 0;
	current_time = 0;
	timer_overflows = 0;
	timer_xmtcalls = 0;
	timer_timereset = 0;

#if !defined(SYS_WINNT)
	/*
	 * Set up the alarm interrupt.	The first comes 2**EVENT_TIMEOUT
	 * seconds from now and they continue on every 2**EVENT_TIMEOUT
	 * seconds.
	 */
# if !defined(VMS)
#  if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME)
	if (timer_create (CLOCK_REALTIME, NULL, &ntpd_timerid) ==
#	ifdef SYS_VXWORKS
		ERROR
#	else
		-1
#	endif
	   )
	{
		fprintf (stderr, "timer create FAILED\n");
		exit (0);
	}
	(void) signal_no_reset(SIGALRM, alarming);
	itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1<<EVENT_TIMEOUT);
	itimer.it_interval.tv_nsec = itimer.it_value.tv_nsec = 0;
	timer_settime(ntpd_timerid, 0 /*!TIMER_ABSTIME*/, &itimer, NULL);
#  else
	(void) signal_no_reset(SIGALRM, alarming);
	itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1<<EVENT_TIMEOUT);
	itimer.it_interval.tv_usec = itimer.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
#  endif
# else /* VMS */
	vmsinc[0] = 10000000;		/* 1 sec */
	vmsinc[1] = 0;
	lib$emul(&(1<<EVENT_TIMEOUT), &vmsinc, &0, &vmsinc);

	sys$gettim(&vmstimer);	/* that's "now" as abstime */

	lib$addx(&vmsinc, &vmstimer, &vmstimer);
	sys$setimr(0, &vmstimer, alarming, alarming, 0);
# endif /* VMS */
#else /* SYS_WINNT */
	/*
	 * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds
	 * Under Windows/NT, 
	 */

	WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL);
	if (WaitableTimerHandle == NULL) {
		msyslog(LOG_ERR, "CreateWaitableTimer failed: %m");
		exit(1);
	}
	else {
		DWORD Period = (1<<EVENT_TIMEOUT) * 1000;
		LARGE_INTEGER DueTime;
		DueTime.QuadPart = Period * 10000i64;
		if (!SetWaitableTimer(WaitableTimerHandle, &DueTime, Period, NULL, NULL, FALSE) != NO_ERROR) {
			msyslog(LOG_ERR, "SetWaitableTimer failed: %m");
			exit(1);
		}
	}

#endif /* SYS_WINNT */
}
Ejemplo n.º 16
0
void t_timekeeper::start_timer(t_timer *t) {
	struct itimerval	itimer;
	long			remain_msec;

	lock();

	// The next interval option is not used
	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = 0;

	// Get duration of the timer to start
	long d = t->get_relative_duration();

	// If no timer is currently running then simply start the timer
	if (timer_list.empty()) {
		timer_list.push_back(t);
		itimer.it_value.tv_sec = d / 1000;
		itimer.it_value.tv_usec = (d % 1000) * 1000;
		setitimer(ITIMER_REAL, &itimer, NULL);

		unlock();
		return;
	}

	// Get remaining duration of current running timer
	getitimer(ITIMER_REAL, &itimer);
	remain_msec = itimer.it_value.tv_sec * 1000 +
		      itimer.it_value.tv_usec / 1000;

	// If the new timer is shorter than the current timer.
	// then the new timer should be run first.
	if (d < remain_msec) {
		// Change running timer to new timer
		itimer.it_value.tv_sec = d / 1000;
		itimer.it_value.tv_usec = (d % 1000) * 1000;
		setitimer(ITIMER_REAL, &itimer, NULL);

		// Calculate the relative duration the timer
		// that was running.
		t_timer *old_timer = timer_list.front();
		old_timer->set_relative_duration(remain_msec - d);

		// Add new timer at the front of the list
		timer_list.push_front(t);

		unlock();
		return;
	}

	// Calculate the relative duration for the new timer
	long new_duration = d - remain_msec;

	// Insert the new timer at the right position in the list.
	list<t_timer *>::iterator i;
	for (i = timer_list.begin(); i != timer_list.end(); i++)
	{
		// skip the first timer
		if (i == timer_list.begin()) continue;

		long dur = (*i)->get_relative_duration();
		if (new_duration < dur) {
			// Adjust relative duration existing timer
			(*i)->set_relative_duration(dur - new_duration);

			// Insert new timer before existing timer
			t->set_relative_duration(new_duration);
			timer_list.insert(i, t);

			unlock();
			return;
		}

		new_duration -= dur;
	}

	// Add the new timer to the end of the list
	t->set_relative_duration(new_duration);
	timer_list.push_back(t);

	unlock();
}
Ejemplo n.º 17
0
Archivo: net.c Proyecto: jmscott/blobio
/*
 *  Do a timed read of some bytes on the network.
 *
 *	>= 0	=> read some bytes
 *	-1	=> read() error
 *	-2	=> timeout
 */
ssize_t
net_read(int fd, void *buf, size_t buf_size, unsigned timeout)
{
	static char n[] = "net_read";

	ssize_t nread;
	int e;
	struct sigaction a;
	struct itimerval t;

	/*
	 *  Set the timeout alarm handler.
	 */
	memset(&a, 0, sizeof a);
	alarm_caught = 0;
	a.sa_handler = catch_SIGALRM;
	a.sa_flags = 0;
	sigemptyset(&a.sa_mask);
	t.it_interval.tv_sec = 0;
	t.it_interval.tv_usec = 0;
	t.it_value.tv_sec = timeout;
	t.it_value.tv_usec = 0;
again:
	/*
	 *  Set the alarm handler.
	 */
	if (sigaction(SIGALRM, &a, (struct sigaction *)0))
		panic3(n, "sigaction(ALRM) failed", strerror(errno));
	/*
	 *  Set the interval time.
	 */
	if (setitimer(ITIMER_REAL, &t, (struct itimerval *)0))
		panic3(n, "setitimer(REAL) failed", strerror(errno));

	nread = read(fd, (void *)buf, buf_size);
	e = errno;

	/*
	 *  Disable timer.
	 *
	 *  Note:
	 *	Does setitimer(t.it_interval.tv_sec == 0) above imply
	 *	timer never refires?
	 */
	t.it_value.tv_sec = 0;
	if (setitimer(ITIMER_REAL, &t, (struct itimerval *)0))
		panic3(n, "setitimer(REAL) reset failed", strerror(errno));

	if (nread < 0) {
		char tbuf[27];

		if (e != EINTR && e != EAGAIN) {
			error3(n, "read() failed", strerror(e));
			errno = e;
			return -1;
		}
		if (!alarm_caught)
			goto again;

		alarm_caught = 0;
		snprintf(tbuf, sizeof tbuf, "timed out after %d secs", timeout);
		error3(n, "alarm caught", tbuf);
		return -2;
	}
	return nread;
}
Ejemplo n.º 18
0
void t_timekeeper::stop_timer(t_object_id id) {
	struct itimerval	itimer;
	long			remain_msec;

	lock();

	// The next interval option is not used
	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = 0;


	if (timer_list.empty()) {
		// Timer already expired or stopped
		unlock();
		return;
	}

	// Find timer
	list<t_timer *>::iterator i = timer_list.begin();
	while (i != timer_list.end()) {
		if ((*i)->get_object_id() == id) break;
		i++;
	}

	if (i == timer_list.end()) {
		// Timer already expired or stopped.
		unlock();
		return;
	}

	// If it is the current running timer, then it must be stopped
	if (i == timer_list.begin()) {
		getitimer(ITIMER_REAL, &itimer);

		// If remaining time is less then 100 msec then let it
		// expire to prevent race condition when timer expires
		// while stopping it now.
		remain_msec = itimer.it_value.tv_sec * 1000 +
			      itimer.it_value.tv_usec / 1000;
		if (remain_msec < 100) {
			stopped = true;
			unlock();
			return;
		}

		// Stop timer
		itimer.it_value.tv_sec = 0;
		itimer.it_value.tv_usec = 0;
		setitimer(ITIMER_REAL, &itimer, NULL);

		// Remove the timer
		MEMMAN_DELETE(timer_list.front());
		delete timer_list.front();
		timer_list.pop_front();

		// If a next timer exists then adjust its relative
		// duration and start it.
		if (!timer_list.empty()) {
			t_timer *next_timer = timer_list.front();
			long dur = next_timer->get_relative_duration();
			dur += remain_msec;
			next_timer->set_relative_duration(dur);
			itimer.it_value.tv_sec = dur / 1000;
			itimer.it_value.tv_usec = (dur % 1000) * 1000;
			setitimer(ITIMER_REAL, &itimer, NULL);
		}

		unlock();
		return;
	}

	// Timer is not the current running timer, so delete it
	// and adjust relative duration of the next timer.
	list<t_timer *>::iterator next = i;
	next++;

	if (next == timer_list.end()) {
		// There is no next timer
		MEMMAN_DELETE(timer_list.back());
		delete timer_list.back();
		timer_list.pop_back();
		unlock();
		return;
	}

	long dur = (*i)->get_relative_duration();
	long dur_next = (*next)->get_relative_duration();
	(*next)->set_relative_duration(dur + dur_next);
	MEMMAN_DELETE(*i);
	delete *i;
	timer_list.erase(i);

	unlock();
}
Ejemplo n.º 19
0
Archivo: net.c Proyecto: jmscott/blobio
/*
 *  Synopsis:
 *	Accept incoming socket.
 *  Returns:
 *	0	new socket accepted
 *	1	timed out the request
 *	-1	accept() error, see errno.
 *  Notes:
 *	Unfortunatley, only the accept() error code is returned to the caller.
 *	The sigaction()/settime() failures cause a panic.
 *
 *	client_fd only changes on success.
 */
int
net_accept(int listen_fd, struct sockaddr *addr, socklen_t *len,
           int *client_fd, unsigned timeout)
{
	int fd, e;
	struct sigaction a;
	struct itimerval t;

	/*
	 *  Set the timeout alarm handler.
	 */
	memset(&a, 0, sizeof a);
	alarm_caught = 0;
	a.sa_handler = catch_SIGALRM;
	a.sa_flags = 0;
	sigemptyset(&a.sa_mask);
	t.it_interval.tv_sec = 0;
	t.it_interval.tv_usec = 0;
	t.it_value.tv_sec = timeout;
	t.it_value.tv_usec = 0;
again:
	/*
	 *  Set the ALRM handler.
	 */
	if (sigaction(SIGALRM, &a, (struct sigaction *)0))
		panic2("io_accept: sigaction(ALRM) failed", strerror(errno));
	/*
	 *  Set the timer
	 */
	if (setitimer(ITIMER_REAL, &t, (struct itimerval *)0))
		panic2("io_accept: setitimer(REAL) failed", strerror(errno));

	/*
	 *  Accept an incoming client connection.
	 */
	fd = accept(listen_fd, addr, len);
	e  = errno;

	/*
	 *  Disable timer.
	 *
	 *  Note:
	 *	Does setitimer(t.it_interval.tv_sec == 0) above imply
	 *	timer never refires?
	 */
	t.it_value.tv_sec = 0;
	t.it_value.tv_usec = 0;
	if (setitimer(ITIMER_REAL, &t, (struct itimerval *)0))
		panic2("io_accept: settimer(REAL, 0) failed", strerror(errno));
	if (fd > -1) {
		*client_fd = fd;
		return 0;
	}

	/*
	 *  Retry or timeout.
	 */
	if (e == EINTR || e == EAGAIN) {
		/*
		 *  Timeout.
		 */
		if (alarm_caught) {
			alarm_caught = 0;
			return 1;
		}
		goto again;
	}
	errno = e;
	return -1;
}
Ejemplo n.º 20
0
/**
* @brief Initialise la lib_can
*
* Ouvre un socket can en lecture écriture. Crée le thread principal de la
* lib_can. Crée une fifo pour la communication entre le programme appelant et la
* lib_can. Crée un timer pour l'appel périodique à la fonction d'envoi.
* Si la libcan est déjà active, alors il ne se passera rien.
*
* @param iface_can chaine pour l'interface CAN (ex : "can0")
*
* @returns 0 si OK, 1 si socket_can KO, 2 FIFO, 3 Thread can, 4 Timer, 5 libcan active
*/
int can_init(const char * iface_can)
{
   /* Socket CAN */
    struct ifreq ifr;
    struct sockaddr_can addr;

   /* Alarme périodique */
    struct itimerval interval;

    if(!can_ok)
    {
	/* Socket CAN */
	if ((socket_can = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
		perror("socket");
		return 1;
	}

	addr.can_family = AF_CAN;

	if(iface_can == NULL)
	{
	    fprintf(stderr, "Utilisation de \"can0\" comme interface can par defaut\n");
	    strcpy(ifr.ifr_name, "can0");
	}
	else strcpy(ifr.ifr_name, iface_can);

	if (ioctl(socket_can, SIOCGIFINDEX, &ifr) < 0) {
		perror("SIOCGIFINDEX");
		return 1;
	}


	addr.can_ifindex = ifr.ifr_ifindex;

	if (bind(socket_can, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		perror("bind");
		return 1;
	}

	/* FIFO */
	while ((tmpnam(fifo)) != NULL){
	    if (mkfifo(fifo, 0600) == 0)
		break;
	    if (errno != EEXIST)
	    {
		perror("Fifo");
		return 2;
	    }
	}
	if (fifo == NULL) return 2;

	if ((fifofd_rd = open(fifo, O_RDONLY | O_NONBLOCK)) < 0) {
	    perror("open error");
	    return 2;
	}
	if ((fifofd_wr= open(fifo, O_WRONLY)) < 0) {
	    perror("open(myfunc) error");
	    return 2;
	}

	/* Lancement du thread */
	if (pthread_create(&can_thread, NULL, can_thread_fct, (void *) NULL)) {
	    perror("erreur pthread");
	    return 3;
	}

	/* Association signal de l'alarme à la fonction can_tx_periodique */
	signal(SIGALRM, can_tx_periodique);

	/* Création de l'alarme périodique : Le process va recevoir des signaux
	 * SIGALRM à intervalles réguliers */
	interval.it_interval.tv_sec = 0;
	interval.it_interval.tv_usec = 10000;
	interval.it_value.tv_sec = 0;
	interval.it_value.tv_usec = 10000;

	if(setitimer(ITIMER_REAL,& interval, NULL))
	{
	    perror("setitimer");
	    return 4;
	}

	can_ok = 1;
    }
    else return 5;

    return 0;
}
Ejemplo n.º 21
0
int main(int argc, char **argv)
{
//    ec_slave_config_t *sc;
    struct sigaction sa;
    struct itimerval tv;

    master = ecrt_request_master(0);
    if (!master)
        return -1;

    domain_input = ecrt_master_create_domain(master);
    domain_output = ecrt_master_create_domain(master);
    if (!domain_input || !domain_output)
    {
        return -1;
    }

    if (!(sc_ana_in = ecrt_master_slave_config(master, AliasAndPositon, VendorID_ProductCode)))
    {
        fprintf(stderr, "Failed to get slave configuration.\n");
        return -1;
    }

#if SDO_ACCESS
    fprintf(stderr, "Creating SDO requests...\n");
    if (!(sdo = ecrt_slave_config_create_sdo_request(sc_ana_in, 0x6061, 0, 1))) // data size 1 ?
    {
        fprintf(stderr, "Failed to create SDO modes_of_operation_display 0x6061 request.\n");
        return -1;
    }
    //EC_WRITE_U16(ecrt_sdo_request_data(sdo), 0xFFFF);

    ecrt_sdo_request_timeout(sdo, 500); // ms
#endif

#if 1
    printf("Configuring PDOs...\n");
    if (ecrt_slave_config_pdos(sc_ana_in, EC_END, slave_0_syncs)) {
        fprintf(stderr, "Failed to configure PDOs.\n");
        return -1;
    }
#endif

    if (ecrt_domain_reg_pdo_entry_list(domain_output, domain_output_regs)) {
            fprintf(stderr, "Output PDO entry registration failed!\n");
            return -1;
        }
    if (ecrt_domain_reg_pdo_entry_list(domain_input, domain_input_regs)) {
            fprintf(stderr, "Input PDO entry registration failed!\n");
            return -1;
        }

    printf("Activating master...\n");
    if (ecrt_master_activate(master))
        return -1;

    if (!(domain_output_pd = ecrt_domain_data(domain_output))) {
        return -1;
    }
    if (!(domain_input_pd = ecrt_domain_data(domain_input))) {
        return -1;
    }

#if PRIORITY
    pid_t pid = getpid();
    if (setpriority(PRIO_PROCESS, pid, -19))
        fprintf(stderr, "Warning: Failed to set priority: %s\n",
                strerror(errno));
#endif

    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGALRM, &sa, 0)) {
        fprintf(stderr, "Failed to install signal handler!\n");
        return -1;
    }

    printf("Starting timer...\n");
    tv.it_interval.tv_sec = 0;
    tv.it_interval.tv_usec = 1000000 / FREQUENCY;
    tv.it_value.tv_sec = 0;
    tv.it_value.tv_usec = 1000;
    if (setitimer(ITIMER_REAL, &tv, NULL)) {
        fprintf(stderr, "Failed to start timer: %s\n", strerror(errno));
        return 1;
    }

    printf("Started.\n");
    while (1) {
        pause();

#if 0
        struct timeval t;
        gettimeofday(&t, NULL);
        printf("%u.%06u\n", t.tv_sec, t.tv_usec);
#endif

        while (sig_alarms != user_alarms) {
            cyclic_task();
            user_alarms++;
        }
    }

    return 0;
}
Ejemplo n.º 22
0
int main(int ac, char **av)
{
	int lc;
	const char *msg;
	struct itimerval *value, *ovalue;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
	}

	setup();		/* global setup */

	/* The following loop checks looping state if -i option given */

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		/* reset tst_count in case we are looping */
		tst_count = 0;

		/* allocate some space for the timer structures */

		if ((value = (struct itimerval *)malloc((size_t)
							sizeof(struct
							       itimerval))) ==
		    NULL) {
			tst_brkm(TBROK, cleanup, "value malloc failed");
		}

		if ((ovalue = (struct itimerval *)malloc((size_t)
							 sizeof(struct
								itimerval))) ==
		    NULL) {
			tst_brkm(TBROK, cleanup, "ovalue malloc failed");
		}

		/* set up some reasonable values */

		value->it_value.tv_sec = SEC1;
		value->it_value.tv_usec = SEC0;
		value->it_interval.tv_sec = 0;
		value->it_interval.tv_usec = 0;
		/*
		 * issue the system call with the TEST() macro
		 * ITIMER_REAL = 0, ITIMER_VIRTUAL = 1 and ITIMER_PROF = 2
		 */

		TEST(setitimer(ITIMER_REAL, value, ovalue));

		if (TEST_RETURN != 0) {
			tst_resm(TFAIL, "call failed - errno = %d - %s",
				 TEST_ERRNO, strerror(TEST_ERRNO));
			continue;
		}

		if (STD_FUNCTIONAL_TEST) {
			/*
			 * call setitimer again with new values.
			 * the old values should be stored in ovalue
			 */
			value->it_value.tv_sec = SEC2;
			value->it_value.tv_usec = SEC0;

			if ((setitimer(ITIMER_REAL, value, ovalue)) == -1) {
				tst_brkm(TBROK, cleanup, "second setitimer "
					 "call failed");
			}

			if (ovalue->it_value.tv_sec <= SEC1) {
				tst_resm(TPASS, "functionality is correct");
			} else {
				tst_brkm(TFAIL, cleanup, "old timer value is "
					 "not equal to expected value");
			}
		} else {
			tst_resm(TPASS, "call succeeded");
		}
	}

	cleanup();
	tst_exit();

}
Ejemplo n.º 23
0
int handle_bgp_open() {
	unsigned char buf[BGP_OPEN_SIZE+BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE+BGP_CAPABILITIES_MP_SIZE];
	struct bgp_open *open_hdr;
	int n;
	unsigned char trash[1];
	unsigned char cap[256];
	unsigned char opt[256];
	unsigned char varopt[2];
	unsigned char mpcap[256];
	struct bgp_opt *bgp_opt_hdr;
	struct bgp_capabilities *bgpc_hdr;
	struct bgp_cap_mp *bgpc_mp_hdr;
	unsigned int total_size;
	int i;
	int v4u = 0;
	struct itimerval new_value;

	// try to read in the open header
	if ((n = read(STDIN_FILENO, buf, BGP_OPEN_SIZE)) == -1) {
		return(-1);
	}

	// make sure we got enough bytes for the open header
	if (n != BGP_OPEN_SIZE) {
//		if (debug) fprintf(stderr, "Invalid open size: %d\n", n);
		// nope, bye-bye
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, 0);
		return(-1);
	}

	// got enough, check the basics

	// make sure we were sent an open packet
	open_hdr = (struct bgp_open *)buf;
	if (open_hdr->bgpo_type != BGP_OPEN) {
//		if (debug) fprintf(stderr, "Invalid packet type: %d\n", open_hdr->bgpo_type);
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_MSG_TYPE);
		return(-1);
	}

	// make sure version is 4
	if (open_hdr->bgpo_version != 4) {
//		if (debug) fprintf(stderr, "Invalid version: %d\n", open_hdr->bgpo_version);
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_OPEN_BADVER);
		return(-1);
	}

	// check the optional parameters for IPv4 Unicast
	if (open_hdr->bgpo_optlen < 2) {
//		if (debug) fprintf(stderr, "No options\n");
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
		return(-1);
	}
//	if (debug) fprintf(stderr, "Options len: %d\n", open_hdr->bgpo_optlen);

	// since bgpo_optlen > 0, read in the rest of the options
	// make sure there aren't a huge number of options
	if (open_hdr->bgpo_optlen > 64) {
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
		return(-1);
	}
	i = 0;
	while (i < open_hdr->bgpo_optlen) {

		// read in the first two bytes of the option header (the type and length)
		if ((n = read(STDIN_FILENO, opt, 2)) != 2) {
//			if (debug) fprintf(stderr, "Options length not read: %d\n", n);
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
			return(-1);
		}
//		if (debug) fprintf(stderr, "Read in %d bytes\n", n);

		bgp_opt_hdr = (struct bgp_opt *)opt;

		// check the cap code
		if (bgp_opt_hdr->bgpopt_type != BGP_OPT_CAP) {
//			if (debug) fprintf(stderr, "Non-Capability option, %d\n", bgp_opt_hdr->bgpopt_type);
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
			return(-1);
		}
//		if (debug) fprintf(stderr, "Processing BGP Capability option, length: %d\n", bgp_opt_hdr->bgpopt_len);

		// check the cap length
		if (i+sizeof(struct bgp_opt)+bgp_opt_hdr->bgpopt_len > open_hdr->bgpo_optlen) {
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
			return(-1);
		}

		// it's less than the overall optlen, so read in the first 2 bytes of the variable portion of this option
		if ((n = read(STDIN_FILENO, varopt, 2)) != 2) {
//			if (debug) fprintf(stderr, "Variable options length not read: %d\n", n);
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
			return(-1);
		}

		bgpc_hdr = (struct bgp_capabilities *)varopt;

		// make sure the length we were passed is valid
		if (sizeof(struct bgp_capabilities)+bgpc_hdr->length != bgp_opt_hdr->bgpopt_len) {
//			if (debug) fprintf(stderr, "Invalid capability length: %d\n", bgpc_hdr->length);
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
			return(-1);
		}

		// see if we got the necessary IPv4 unicast capability advertisement from the peer
		if (bgpc_hdr->type == BGP_CAPCODE_MP && bgpc_hdr->length == 4) {
//			if (debug) fprintf(stderr, "Processing BGP MP Capability option, length: %d\n", bgpc_hdr->length);

			// yep read in the MP capabilities struct
			if ((n = read(STDIN_FILENO, mpcap, 4)) != 4) {
//				if (debug) fprintf(stderr, "MP Cap options length not read: %d\n", n);
				bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
				return(-1);
			}

			bgpc_mp_hdr = (struct bgp_cap_mp *)mpcap;
//			if (debug) fprintf(stderr, "%08x, AFI: %d, SAFI: %d\n", *((unsigned int *)mpcap), ntohs(bgpc_mp_hdr->afi), bgpc_mp_hdr->safi);
			if (ntohs(bgpc_mp_hdr->afi) == BGP_AFI_IPV4 && bgpc_mp_hdr->safi == BGP_SAFI_UNICAST) { 
//				if (debug) fprintf(stderr, "Received MP capability AFI=IPv4, SAFI=unicast\n");
				v4u = 1;
			}
		} else if (bgpc_hdr->type == 65 && bgpc_hdr->length == 4) {
			// ignore 4-byte AS capability, but read past it all the same
			if ((n = read(STDIN_FILENO, mpcap, 4)) != 4) {
//				if (debug) fprintf(stderr, "MP Cap options length not read: %d\n", n);
				bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
				return(-1);
			}
		} else {
//			if (debug) fprintf(stderr, "Don't recognize BGP capability type %d\n", bgpc_hdr->type);
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
			return(-1);
		}
		
		i += BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE+bgpc_hdr->length;
//		if (debug) fprintf(stderr, "i: %d\n", i);
	}

	if (!v4u) {
		// didn't find the IPv4 unicast required cap...
//		if (debug) fprintf(stderr, "Didn't find MP capability AFI=IPv4, SAFI=unicast\n");
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_CAP_BADCAPC);
		return(-1);
	}

	// check the hold time
	peer.max_hold_time = ntohs(open_hdr->bgpo_holdtime);
	if (peer.max_hold_time < 3 && peer.max_hold_time != 0) {
//		if (debug) fprintf(stderr, "Invalid hold time: %d\n", open_hdr->bgpo_holdtime);
		bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_OPEN_BADHOLD);
		return(-1);
	}
	if (peer.max_hold_time > OUR_HOLD_TIME) {
		peer.max_hold_time = OUR_HOLD_TIME;
	}

	// set a timer to re-send a keepalive as needed (1/3 of the requested hold time)
	if (peer.max_hold_time != 0) {
		new_value.it_interval.tv_sec = peer.max_hold_time/3;
		new_value.it_interval.tv_usec = 0;
		new_value.it_value.tv_sec = peer.max_hold_time/3;
		new_value.it_value.tv_usec = 0;
		
		if ((i = setitimer(ITIMER_REAL, &new_value, NULL)) != 0) {
//			if (debug) fprintf(stderr, "Unable to set itimer: %d\n", i);
			bgp_send_notification(BGP_NOTIFY_MAJOR_OPEN, BGP_NOTIFY_MINOR_OPEN_BADHOLD);
			return(-1);
		}
	}

	// capabilites look good...let's reply

	// grab the peer ID and AS and put them in the bgp_peer struct
	peer.bgp_peer_id = ntohl(open_hdr->bgpo_id);
	peer.bgp_peer_as = ntohs(open_hdr->bgpo_myas);

	// everything looks ok in the open we received
	bzero(buf, BGP_OPEN_SIZE+BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE+BGP_CAPABILITIES_MP_SIZE);
	open_hdr = (struct bgp_open *)buf;
	// so send back our open and a keepalive
	// marker = all 1's
	memset(open_hdr, 0xFF, 16);

	// length = BGP_OPEN_SIZE
	open_hdr->bgpo_len = htons(BGP_OPEN_SIZE+BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE+BGP_CAPABILITIES_MP_SIZE);
	
	// type = BGP_OPEN
	open_hdr->bgpo_type = BGP_OPEN;

	// version = 4
	open_hdr->bgpo_version = 4;

	// AS = MYAS
	open_hdr->bgpo_myas = htons(MYAS);

	// holdtime = OUR_HOLD_TIME
	open_hdr->bgpo_holdtime = htons(OUR_HOLD_TIME);

	// ID = 192.168.1.1
	open_hdr->bgpo_id = inet_addr("192.168.1.1");

	// optlen = large enough to handle MP IPv4 unicast capability advertisement
	open_hdr->bgpo_optlen = BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE+BGP_CAPABILITIES_MP_SIZE;

	// set up the BGP option header
	bgp_opt_hdr = (struct bgp_opt *)opt;
	bgp_opt_hdr->bgpopt_type = BGP_OPT_CAP;
	bgp_opt_hdr->bgpopt_len = BGP_CAPABILITIES_SIZE+BGP_CAPABILITIES_MP_SIZE;
	memcpy(buf+BGP_OPEN_SIZE, opt, BGP_OPT_SIZE);

	// set up the MP capability header
	bgpc_hdr = (struct bgp_capabilities *)varopt;
	bgpc_hdr->type = BGP_CAPCODE_MP;
	bgpc_hdr->length = 4;
	memcpy(buf+BGP_OPEN_SIZE+BGP_OPT_SIZE, varopt, BGP_CAPABILITIES_SIZE);

	// set up the MP IPv4 Unicast capability
	bgpc_mp_hdr = (struct bgp_cap_mp *)mpcap;
	bgpc_mp_hdr->afi = htons(BGP_AFI_IPV4);
	bgpc_mp_hdr->res = 0;
	bgpc_mp_hdr->safi = BGP_SAFI_UNICAST;
	memcpy(buf+BGP_OPEN_SIZE+BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE, mpcap, BGP_CAPABILITIES_MP_SIZE);
	
	// send it
	total_size = BGP_OPEN_SIZE+BGP_OPT_SIZE+BGP_CAPABILITIES_SIZE+BGP_CAPABILITIES_MP_SIZE;
	if (send(STDOUT_FILENO, buf, total_size, 0) != total_size) {
//		if (debug) fprintf(stderr, "Sending of open failed\n");
		return(-1);
	}
//	if (debug) fprintf(stderr, "Sent open packet\n");

	if (bgp_send_keepalive()) {
		return(-1);
	}

	peer.bgp_state = BGP_STATE_ESTAB;

	// successfully opened our BGP connection
	return(0);
		
}
Ejemplo n.º 24
0
//---------------------------------------------------------------------------//
bool CAddInNative::CallAsProc(const long lMethodNum,
                    tVariant* paParams, const long lSizeArray)
{ 
    switch(lMethodNum)
    { 
    case eMethEnable:
        m_boolEnabled = true;
        break;
    case eMethDisable:
        m_boolEnabled = false;
		//_tmain(0, NULL);
        break;
    case eMethShowInStatusLine:
        if (m_iConnect && lSizeArray)
        {
            tVariant *var = paParams;
            m_iConnect->SetStatusLine(var->pwstrVal);
#ifndef __linux__
            Sleep(5000);
#else
            sleep(5);
#endif
        }
        break;
    case eMethStartTimer:
        pAsyncEvent = m_iConnect;
        /* The task of length of turn of messages
        if (m_iConnect)
            m_iConnect->SetEventBufferDepth(4000);
        */
#ifndef __linux__
        m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
#else
        struct sigaction sa;
        struct itimerval tv;
        memset(&tv, 0, sizeof(tv));

        sa.sa_handler = MyTimerProc;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART; 
        sigaction(SIGALRM, &sa, NULL);
        tv.it_interval.tv_sec = 1;
        tv.it_value.tv_sec = 1;
        setitimer(ITIMER_REAL, &tv, NULL);
#endif
        break;
    case eMethStopTimer:
#ifndef __linux__
        if (m_uiTimer != 0)
            ::KillTimer(NULL,m_uiTimer);
#else
        alarm(0);
#endif
        m_uiTimer = 0;
        pAsyncEvent = NULL;
        break;
    case eMethShowMsgBox:
        {
            if(eAppCapabilities1 <= g_capabilities)
            {
                IAddInDefBaseEx* cnn = (IAddInDefBaseEx*)m_iConnect;
                IMsgBox* imsgbox = (IMsgBox*)cnn->GetInterface(eIMsgBox);
                if (imsgbox)
                {
                    IPlatformInfo* info = (IPlatformInfo*)cnn->GetInterface(eIPlatformInfo);
                    assert(info);
                    const IPlatformInfo::AppInfo* plt = info->GetPlatformInfo();
                    if (!plt)
                        break;
                    tVariant retVal;
                    tVarInit(&retVal);
                    if(imsgbox->Confirm(plt->AppVersion, &retVal))
                    {
                        bool succeed = TV_BOOL(&retVal);
                        if (succeed)
						{
							imsgbox->Alert(L"OKFFFFF");
						}
                        else
                            imsgbox->Alert(L"Cancel");
                    }
                }
            }
        }
        break;
	case eMethInit:
		{
			init();
		}
		break;
	case eMethReg:
		{
			reg_on_srv();
		}
		break;
	case eMethMakeCall:
		{
			make_call(unicode_to_pj_str(paParams->pwstrVal));
		}
		break;
	case eMethsetNullDev:
		{
			setNullDev();
		}
		break;
    default:
        return false;
    }

    return true;
}
Ejemplo n.º 25
0
void Client::RunTCP( void )
{
    unsigned long currLen = 0;
    struct itimerval it;
    max_size_t totLen = 0;

    int err;

    char* readAt = mBuf;

    // Indicates if the stream is readable
    bool canRead = true, mMode_Time = isModeTime( mSettings );

    ReportStruct *reportstruct = NULL;

    // InitReport handles Barrier for multiple Streams
    mSettings->reporthdr = InitReport( mSettings );
    reportstruct = new ReportStruct;
    reportstruct->packetID = 0;

    lastPacketTime.setnow();
    if ( mMode_Time ) {
        memset (&it, 0, sizeof (it));
        it.it_value.tv_sec = (int) (mSettings->mAmount / 100.0);
        it.it_value.tv_usec = (int) 10000 * (mSettings->mAmount -
                                             it.it_value.tv_sec * 100.0);
        err = setitimer( ITIMER_REAL, &it, NULL );
        if ( err != 0 ) {
            perror("setitimer");
            exit(1);
        }
    }
    do {
        // Read the next data block from
        // the file if it's file input
        if ( isFileInput( mSettings ) ) {
            Extractor_getNextDataBlock( readAt, mSettings );
            canRead = Extractor_canRead( mSettings ) != 0;
        } else {
            canRead = true;
        }

        // perform write
        currLen = write( mSettings->mSock, mBuf, mSettings->mBufLen );
        if ( currLen < 0 ) {
            WARN_errno( currLen < 0, "write2" );
            break;
        }
        totLen += currLen;

        if(mSettings->mInterval > 0) {
            gettimeofday( &(reportstruct->packetTime), NULL );
            reportstruct->packetLen = currLen;
            ReportPacket( mSettings->reporthdr, reportstruct );
        }

        if ( !mMode_Time ) {
            /* mAmount may be unsigned, so don't let it underflow! */
            if( mSettings->mAmount >= currLen ) {
                mSettings->mAmount -= currLen;
            } else {
                mSettings->mAmount = 0;
            }
        }

    } while ( ! (sInterupted  ||
                 (!mMode_Time  &&  0 >= mSettings->mAmount)) && canRead );

    // stop timing
    gettimeofday( &(reportstruct->packetTime), NULL );

    // if we're not doing interval reporting, report the entire transfer as one big packet
    if(0.0 == mSettings->mInterval) {
        reportstruct->packetLen = totLen;
        ReportPacket( mSettings->reporthdr, reportstruct );
    }
    CloseReport( mSettings->reporthdr, reportstruct );

    DELETE_PTR( reportstruct );
    EndReport( mSettings->reporthdr );
}
Ejemplo n.º 26
0
/*
 * main - parse arguments and handle options
 */
int
main(
	int argc,
	char *argv[]
	)
{
	int fd;
	struct sgttyb ttyb;
	struct itimerval itimer;

#ifdef STREAM
	magic[0] = 0;
#endif

	{
	    int ct = optionProcess( &clktestOptions, argc, argv );
	    if (HAVE_OPT(COMMAND) && (strlen(OPT_ARG(COMMAND)) == 0)) {
		fputs( "The command option string must not be empty\n", stderr );
		USAGE( EXIT_FAILURE );
	    }

	    if ((argc -= ct) != 1) {
		fputs( "Missing tty device name\n", stderr );
		USAGE( EXIT_FAILURE );
	    }
	    argv += ct;
	}
#ifdef STREAM
	if (!strlen(magic))
	    strcpy(magic,DEFMAGIC);
#endif

	fd = open(*argv, HAVE_OPT(TIMEOUT) ? O_RDWR : O_RDONLY, 0777);
	if (fd == -1) {
		fprintf(stderr, "%s: open(%s): ", progname, *argv);
		perror("");
		exit(1);
	}

	if (ioctl(fd, TIOCEXCL, (char *)0) < 0) {
		(void) fprintf(stderr, "%s: ioctl(TIOCEXCL): ", progname);
		perror("");
		exit(1);
	}

	/*
	 * If we have the clock discipline, set the port to raw.  Otherwise
	 * we run cooked.
	 */
	ttyb.sg_ispeed = ttyb.sg_ospeed = speed;
#ifdef CLKLDISC
	ttyb.sg_erase = (char)magic1;
	ttyb.sg_kill = (char)magic2;
#endif
	ttyb.sg_flags = (short)ttflags;
	if (ioctl(fd, TIOCSETP, (char *)&ttyb) < 0) {
		(void) fprintf(stderr, "%s: ioctl(TIOCSETP): ", progname);
		perror("");
		exit(1);
	}

	if (fcntl(fd, F_SETOWN, getpid()) == -1) {
		(void) fprintf(stderr, "%s: fcntl(F_SETOWN): ", progname);
		perror("");
		exit(1);
	}

#ifdef CLKLDISC
	{
		int ldisc;
		ldisc = CLKLDISC;
		if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) {
			(void) fprintf(stderr, "%s: ioctl(TIOCSETD): ", progname);
			perror("");
			exit(1);
		}
	}
#endif
#ifdef STREAM
	if (ioctl(fd, I_POP, 0) >=0 ) ;
	if (ioctl(fd, I_PUSH, "clk") < 0) {
		(void) fprintf(stderr, "%s: ioctl(I_PUSH): ", progname);
		perror("");
		exit(1);
	}
	if (ioctl(fd, CLK_SETSTR, magic) < 0) {
		(void) fprintf(stderr, "%s: ioctl(CLK_SETSTR): ", progname);
		perror("");
		exit(1);
	}
#endif


	(void) gettimeofday(&lasttv, (struct timezone *)0);
	if (HAVE_OPT(TIMEOUT)) {
		/*
		 * set non-blocking, async I/O on the descriptor
		 */
		iosig = 0;
		(void) signal(SIGIO, ioready);
		if (fcntl(fd, F_SETFL, FNDELAY|FASYNC) < 0) {
			(void) fprintf(stderr, "%s: fcntl(F_SETFL): ",
				       progname);
			perror("");
			exit(1);
		}

		/*
		 * Set up the alarm interrupt.
		 */
		wasalarmed = 0;
		(void) signal(SIGALRM, alarming);
		timeout.tv_sec = OPT_VALUE_TIMEOUT;
		itimer.it_interval = itimer.it_value = timeout;
		setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
		doboth(fd);
	}
	doioonly(fd);
}
Ejemplo n.º 27
0
void timer_handler( int signum )
{
    char buf[MAX_SMESG_LEN+1], * x = &buf[7]; /* buffer for outgoing messages */
    PQUEUE *temp, *r;
    int i, j;

    #ifdef DEBUG_BARF
        BARF( "timer expired", signum );
    #endif

    switch( server_status ) {
        case SHUFFL://TODO: remove DC players before here?
            if( (c_in_tab+p_in_lob) < min_ppplaying ) {/* !Enough Players */
                #ifdef DEBUG_BARF
                    BARF( "!enough players", c_in_tab+p_in_lob );
                #endif
                if( p_in_tab ) { /* Re-Enqueue Table Players Into Lobby */
                    c_in_tab = p_in_tab = 0; /* Stand Up */
                    while( (temp = warlord.next) ) { //TODO: just append remainder of warlord list to lobby and reset scumbag
                        /* Remove DC Players */
                        if( warlord.who->status != DIS_CONN ) {
                            ++p_in_lob;
                            warlord.who->status = IN_LOBBY;
                            lobby_last->who = warlord.who;
                            lobby_last = lobby_last->next = CALLOC( 1, PQUEUE ); /* WARNING: assumes calloc is successfull */
                        } else init_player( warlord.who-player );//init_p( warlord.who );
                        warlord.who = warlord.next->who;
                        warlord.next = warlord.next->next;
                        free( temp );
                    } /* End de-queue While */
//TODO: WORKING: append warlord to lobby and hold dc players in another ll
//                     lobby_last->who = warlord.who;
//                     lobby_last->next = warlord.next;
//                     lobby_last = scumbag;
//                     warlord.who = NULL; warlord.next = NULL;
                    scumbag = &warlord;
//                     //TODO: remove dc players from appended section, set status
                    send_slobb_mesg();
                }/* End Moved Players to Lobby If */
                server_status = ENQING;
                hand_status = HAND_1; /* Reset Hand For Next Players */
                return;
            } /* End !Enough Players Remain to Play If */

            if( hand_status == HAND_1 ) need_club3 = true;
            else {
                server_status = SWAPIN;
                #ifdef DEBUG_BARF
                    BARF( "PLAYING ANOTHER HAND", hand_status );
                #endif
            }/* End !HAND_1 Else */

            /* Move to Table */
            p_in_tab = 0; /* Everyone Stand Up */
            while( (temp = warlord.next) ) {
                /* Remove DC Players */
                if( warlord.who->status != DIS_CONN ) {
                    table[p_in_tab] = warlord.who;
                    ++table[p_in_tab++]->hands; /* SGUI  - Track Qt Played Hands */
                } else init_player( warlord.who-player );//init_p( warlord.who );
                warlord.who = warlord.next->who;
                warlord.next = warlord.next->next;
                free( temp );
            } /* End de-queue While */
            scumbag = &warlord;

            /* Move in From Lobby if Room */
            if(( p_in_tab < MAX_PPPLAYING )&&( p_in_lob )) {
                sprintf( buf, "[slobb|" ); /* Correct qt Filled in Later */

                /* Sit at Table */
                while( p_in_tab < MAX_PPPLAYING ) {
                    if( !lobby_head.who ) break;
                    table[p_in_tab++] = lobby_head.who;
                    lobby_head.who = lobby_head.next->who;
                    temp = lobby_head.next;
                    lobby_head.next = lobby_head.next->next;
                    free( temp ); --p_in_lob;
                }/* End Room@Table While */

                *x++ = '0'+ (int)( p_in_lob / 10 );
                *x++ = '0'+ ( p_in_lob % 10 );
                *x++ = '|';

                lobby_last = r = &lobby_head;
                while( r->who ) {
                    sprintf( x, "%s,", r->who->name );
                    x += 9;
                    lobby_last = r;
                    r = r->next;
                }/* End Current Player Exists Else */
                *(x-1) = ']'; *x = 0;
                broadcast( buf, 10+(9*p_in_lob) );
            }/* End New Players Join If */
            c_in_tab = p_in_tab;
            for( i = c_in_tab; i < MAX_PPPLAYING; i++ ) table[i] = NULL;

            /* Deal */
            assert( p_in_tab >= DEF_MIN_PLAYERS );
//             deal( time( NULL ) );
            if( deal( time( NULL ) ) ) { /* Returns True if Failed */
                /* If Got Here then !Enough Players Anymore */
                for( i = 0; i < p_in_tab; i++ ) {
                    lobby_last->who = table[i];
                    lobby_last = lobby_last->next = CALLOC( 1, PQUEUE ); /* WARNING: assumes calloc is successfull */
                    ++p_in_lob;
                } /* End Re-Enqueue For */
                send_slobb_mesg();
                server_status = ENQING;
                return;
            }/* End Failed Deal If */

            sprintf( buf, "[shand|" );
            for( i = 0; i < c_in_tab; i++ ) {
                x = &buf[7];
                for( j = 0; j < MAX_PHAND_LEN; j++ ) {
                    *x++ = '0'+ (int)( table[i]->hand[j] / 10 );
                    *x++ = '0'+ ( table[i]->hand[j] % 10 );
                    *x++ = ',';
                }/* End card in hand For */
                 *(x-1) = ']'; *x = 0;
                if( Write( table[i]->socketfd, buf, 61 ) < 0 )
                    ERROR( "write", strerror(errno), i );
            }/* End table[i] For */

            if( server_status != SWAPIN ) {
                send_tabl_mesg();
                server_status = ACTIVE;
            } else { /* Request Swap */
                char* cd = &(table[p_in_tab-1]->hand[MAX_PHAND_LEN-1]);
                while( *cd == 52 ) --cd; /* Find Highest Card */
                swapped_cd = *cd;
                assert( (unsigned)swapped_cd < 52 );/* ERROR CHECK */
                if( use_gui ) /* Decrement Count -- SGUI */
                    --deck[swapped_cd]->count[(swapped_cd-(swapped_cd%4))/4];
                deck[swapped_cd] = table[0]; /* Give Warlord Swappeed Card */
                if( use_gui ) /* Increment Count -- SGUI */
                    ++deck[swapped_cd]->count[(swapped_cd-(swapped_cd%4))/4];
                /* Update Scores For SGUI */
                ++table[0]->score; --table[p_in_tab-1]->score;
                /* Notify Clients of Change */
                ( swapped_cd < 10 ) ?
                    sprintf( buf, "[swapw|%c%d]", '0', swapped_cd ):
                    sprintf( buf, "[swapw|%d]", swapped_cd );
                if( Write( table[0]->socketfd, buf, 10 ) < 0 )
                    ERROR( "write", strerror(errno), table[0]->socketfd );
            }/* End SWAPIN Else */

            timer.it_value.tv_sec = ertimeout;
            setitimer( ITIMER_REAL, &timer, NULL );
            break;
        case ACTIVE:
            #ifdef DEBUG_BARF
                BARF( "Testing: server_status is ACTIVE.", ACTIVE );
            #endif
            for( i = 0; i < MAX_PPPLAYING; i++ )
                if( player[i].status == ACTIVE_P ) break;
            /* No Break */
        case SWAPIN:
            #ifdef DEBUG_BARF
                if( server_status != ACTIVE )
                    BARF( "Testing: server_status is SWAPIN", SWAPIN );
            #endif
            if( server_status != ACTIVE ) i = table[0] - &player[0];
            if( strike( i, PLAY_TIMEOUT ) )
                remove_player( i, buf, gfds );
            else if( server_status == ACTIVE ) send_tabl_mesg();
            timer.it_value.tv_sec = ertimeout;
            setitimer( ITIMER_REAL, &timer, NULL );
            break;
        default: /* ENQING */
            #ifdef DEBUG_BARF
                ERROR( "timer_h", "Timer went off while ENQING", signum );
            #endif
            break;
    }/* End server_status Switch */
    return;
}/* End timer_handler Func */
Ejemplo n.º 28
0
meter_server()
{
  char packet[1500];
  int packsize, restsize, queuesize, chunksize, pn, range;
  long now, percent, interval;
  struct itimerval new_val, old_val;

  signal(SIGALRM, meter_alarm_handler);

  while (true)
    {
      interval = SHARED_DATA->Wholine_Rate; /* In milliseconds */
      new_val.it_value.tv_sec = interval / 1000;
      new_val.it_value.tv_usec = (interval % 1000) * 1000;
      new_val.it_interval.tv_sec = 0;
      new_val.it_interval.tv_usec = 0;
      setitimer(ITIMER_REAL, &new_val, &old_val);
      sigpause(0);

      packsize = 4 * N_Interps + PACKET_HEAD_SIZE;
      restsize = packsize - 3;

      packet[0] = WHOLINE_INFO;
      packet[1] = restsize >> 8;
      packet[2] = restsize;
      packet[3] = WHOLINE_VERSION;
      packet[4] = N_Interps;
      packet[5] = N_Interps;

      queuesize = SHARED_DATA->Work_Queue.queue_count;
      packet[6] = queuesize >> 8;
      packet[7] = queuesize;

      chunksize = Local_Chunk_Size;
      packet[8] = chunksize >> 24;
      packet[9] = chunksize >> 16;
      packet[10] = chunksize >> 8;
      packet[11] = chunksize;

      now = System_Clock();
      packet[12] = now >> 24;
      packet[13] = now >> 16;
      packet[14] = now >> 8;
      packet[15] = now;

      for (pn = 0; pn < N_Interps; pn++)
	{
	  packet[pn + PACKET_HEAD_SIZE] = SHARED_DATA->Processor_Zone[pn];
	  packet[pn + PACKET_HEAD_SIZE + N_Interps] = 0;
	  packet[pn + PACKET_HEAD_SIZE + N_Interps + N_Interps] = 0;
	  range = (SHARED_DATA->Memory_Table[pn].Free_Top -
		   SHARED_DATA->Memory_Table[pn].Free_Bottom);
	  percent = (100 * range) / Local_Chunk_Size;
	  if (percent < 0) percent = 0;
	  if (percent > 100) percent = 100;
	  percent = 100 - percent;
	  packet[pn + PACKET_HEAD_SIZE + N_Interps + N_Interps + N_Interps] = percent;
	  if (Debug_Flags[23])
	    printf("pn=%d FT=0x%x FB=0x%x r=0x%x (%d/%d) per=%d\n",
		   pn, SHARED_DATA->Memory_Table[pn].Free_Top,
		   SHARED_DATA->Memory_Table[pn].Free_Bottom,
		   range, range, Local_Chunk_Size, percent);
	}

      while(atomior(&SHARED_DATA->Lisp_Output_Lock, 0x8000) != 0);
      write(SHARED_DATA->Lisp_Output_Pipe[WRITE_TO_PIPE],
	    packet, packsize);
      SHARED_DATA->Lisp_Output_Lock = 0;
    }
}
Ejemplo n.º 29
0
int
main(int argc, char *argv[])
{
	int nfds;
	fd_set fdvar;
	time_t ttime;
	struct itimerval tval;

	argv0 = argv;
	argv++, argc--;
	while (argc > 0 && **argv == '-') {
		if (strcmp(*argv, "-s") == 0) {
			supplier = 1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-q") == 0) {
			supplier = 0;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-R") == 0) {
			noteremoterequests++;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-S") == 0) {
			dosap = 0;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-t") == 0) {
			tracepackets++;
			argv++, argc--;
			ftrace = stderr;
			tracing = 1; 
			continue;
		}
		if (strcmp(*argv, "-g") == 0) {
			gateway = 1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-l") == 0) {
			gateway = -1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-N") == 0) {
			dognreply = 0;
			argv++, argc--;
			continue;
		}
		fprintf(stderr,
			"usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N ]\n");
		exit(1);
	}
	
	
#ifndef DEBUG
	if (!tracepackets)
		daemon(0, 0);
#endif
	openlog("IPXrouted", LOG_PID, LOG_DAEMON);

	addr.sipx_family = AF_IPX;
	addr.sipx_len = sizeof(addr);
	addr.sipx_port = htons(IPXPORT_RIP);
	ipx_anynet.s_net[0] = ipx_anynet.s_net[1] = -1;
	ipx_netmask.sipx_addr.x_net = ipx_anynet;
	ipx_netmask.sipx_len = 6;
	ipx_netmask.sipx_family = AF_IPX;
	r = socket(AF_ROUTE, SOCK_RAW, 0);
	/* later, get smart about lookingforinterfaces */
	if (r)
		shutdown(r, SHUT_RD); /* for now, don't want reponses */
	else {
		fprintf(stderr, "IPXrouted: no routing socket\n");
		exit(1);
	}
	ripsock = getsocket(SOCK_DGRAM, 0, &addr);
	if (ripsock < 0)
		exit(1);

	if (dosap) {
		addr.sipx_port = htons(IPXPORT_SAP);
		sapsock = getsocket(SOCK_DGRAM, 0, &addr);
		if (sapsock < 0)
			exit(1);
	} else
		sapsock = -1;

	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 */
	if (argc > 0)
		traceon(*argv);
	/*
	 * Collect an initial view of the world by
	 * snooping in the kernel.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */
	rtinit();
	sapinit();
	ifinit();
	if (supplier < 0)
		supplier = 0;
	/* request the state of the world */
	msg->rip_cmd = htons(RIPCMD_REQUEST);
	msg->rip_nets[0].rip_dst = ipx_anynet;
	msg->rip_nets[0].rip_metric =  htons(HOPCNT_INFINITY);
	msg->rip_nets[0].rip_ticks =  htons(-1);
	toall(sndmsg, NULL, 0);

	if (dosap) {
		sap_msg->sap_cmd = htons(SAP_REQ);
		sap_msg->sap[0].ServType = htons(SAP_WILDCARD);
		toall(sapsndmsg, NULL, 0);
	}

	signal(SIGALRM, catchtimer);
	signal(SIGHUP, hup);
	signal(SIGINT, hup);
	signal(SIGEMT, fkexit);
	signal(SIGINFO, getinfo);
 
	tval.it_interval.tv_sec = TIMER_RATE;
	tval.it_interval.tv_usec = 0;
	tval.it_value.tv_sec = TIMER_RATE;
	tval.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &tval, NULL);

	nfds = 1 + max(sapsock, ripsock);

	for (;;) {
		if (dobcast) {
			dobcast = 0;
			lastbcast = time(NULL);
			timer();
		}

		FD_ZERO(&fdvar);
		if (dosap) {
			FD_SET(sapsock, &fdvar);
		}
		FD_SET(ripsock, &fdvar);

		if(select(nfds, &fdvar, NULL, NULL, NULL) < 0) {
			if(errno == EINTR)
				continue;
			perror("during select");
			exit(1);
		}

		if(FD_ISSET(ripsock, &fdvar))
			process(ripsock, RIP_PKT);

		if(dosap && FD_ISSET(sapsock, &fdvar))
			process(sapsock, SAP_PKT);

		ttime = time(NULL);
		if (ttime > (lastbcast + TIMER_RATE + (TIMER_RATE * 2 / 3))) {
			dobcast = 1;
			syslog(LOG_ERR, "Missed alarm");
		}
	}
}
Ejemplo n.º 30
0
/*
 * Play some audio and pass a status message upstream, if applicable.
 * Returns 0 on success.
 */
int
sun_audio_play(unsigned char *rawbuf, long buflen, struct cdda_block *blk)
{
	int			i;
	short			*buf16;
	int			alarmcount = 0;
	struct itimerval	it;
	long playablelen;

	alarm(1);
  playablelen = dev_audio_convert(rawbuf, buflen, blk);
	while (write(aufd, rawbuf, playablelen) <= 0)
		if (errno == EINTR)
		{
			if (! raw_audio && alarmcount++ < 5)
			{
				/*
				 * 8KHz /dev/audio blocks for several seconds
				 * waiting for its queue to drop below a low
				 * water mark.
				 */
				wmaudio_send_status();
				timerclear(&it.it_interval);
				timerclear(&it.it_value);
				it.it_value.tv_usec = 500000;
				setitimer(ITIMER_REAL, &it, NULL);
				continue;
			}

/*			close(aufd);
			close(aucfd);
			wmaudio_init();
*/ sun_audio_stop();
			alarm(2);
			continue;
		}
		else
		{
			blk->status = WM_CDM_CDDAERROR;
			return (-1);
		}
	alarm(0);

	/*
	 * Mark this spot in the audio stream.
	 *
	 * Marks don't always succeed (if the audio buffer is empty
	 * this call will block forever) so do it asynchronously.
	 */
	fcntl(aufd, F_SETFL, O_NONBLOCK);
	if (write(aufd, rawbuf, 0) < 0)
	{
		if (errno != EAGAIN)
			perror("audio mark");
	}
	else
		qtail = (qtail + 1) % QSIZE;

	fcntl(aufd, F_SETFL, 0);

	queue[qtail] = *blk;

	if (wmaudio_send_status() < 0)
		return (-1);
	else
		return (0);
}