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; }
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); }
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)); } } }
// 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; }
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; } } }
/* * 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; }
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, ¶m)) 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; }
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 }
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; }
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); } } }
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)); } } }
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; }
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; }
/* * 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 */ }
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(); }
/* * 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; }
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(); }
/* * 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; }
/** * @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; }
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; }
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(); }
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); }
//---------------------------------------------------------------------------// 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; }
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 ); }
/* * 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); }
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 */
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; } }
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"); } } }
/* * 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); }