void WebRtcEndpointImpl::postConstructor () { BaseRtpEndpointImpl::postConstructor (); handlerOnIceCandidate = register_signal_handler (G_OBJECT (element), "on-ice-candidate", std::function <void (GstElement *, KmsIceCandidate *) > (std::bind (&WebRtcEndpointImpl::onIceCandidate, this, std::placeholders::_2) ), std::dynamic_pointer_cast<WebRtcEndpointImpl> (shared_from_this() ) ); handlerOnIceGatheringDone = register_signal_handler (G_OBJECT (element), "on-ice-gathering-done", std::function <void (GstElement *) > (std::bind (&WebRtcEndpointImpl::onIceGatheringDone, this) ), std::dynamic_pointer_cast<WebRtcEndpointImpl> (shared_from_this() ) ); handlerOnIceComponentStateChanged = register_signal_handler (G_OBJECT (element), "on-ice-component-state-changed", std::function <void (GstElement *, guint, guint, guint) > (std::bind (&WebRtcEndpointImpl::onIceComponentStateChanged, this, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) ), std::dynamic_pointer_cast<WebRtcEndpointImpl> (shared_from_this() ) ); }
void as_signal_setup() { register_signal_handler(SIGABRT, as_sig_handle_abort); register_signal_handler(SIGBUS, as_sig_handle_bus); register_signal_handler(SIGFPE, as_sig_handle_fpe); register_signal_handler(SIGHUP, as_sig_handle_hup); register_signal_handler(SIGILL, as_sig_handle_ill); register_signal_handler(SIGINT, as_sig_handle_int); register_signal_handler(SIGQUIT, as_sig_handle_quit); register_signal_handler(SIGSEGV, as_sig_handle_segv); register_signal_handler(SIGTERM, as_sig_handle_term); // Block SIGPIPE signal when there is some error while writing to pipe. The // write() call will return with a normal error which we can handle. struct sigaction sigact; memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = SIG_IGN; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask, SIGPIPE); if (sigaction(SIGPIPE, &sigact, NULL) != 0) { cf_warning(AS_AS, "could not block the SIGPIPE signal"); } }
int main(int argc, char **argv) { //signal(SIGALRM, handler); //struct sigaction act, oact; //act.sa_handler = handler; register_signal_handler(SIGALRM, handler); printf("Sleeping...\n"); usleep(1000000000); }
/** The main(). It parses the command line, setup the parms, ask the scheduler for signal to proceed, and then starts skysim to do sky coverage. */ int main(int argc, const char *argv[]){ dirstart=mygetcwd(); char *scmd=argv2str(argc, argv, " "); ARG_S* arg=parse_args(argc,argv); /*In detach mode send to background and disable drawing*/ if(arg->detach){ daemonize(); }else{ redirect(); } info2("%s\n", scmd); info2("Output folder is '%s'. %d threads\n",arg->dirout, arg->nthread); skyc_version(); /*register signal handler */ register_signal_handler(skyc_signal_handler); /* Ask job scheduler for permission to proceed. If no CPUs are available, will block until ones are available. if arg->force==1, will run immediately. */ scheduler_start(scmd,arg->nthread,0,!arg->force); /*setting up parameters before asking scheduler to check for any errors. */ dirsetup=stradd("setup",NULL); PARMS_S * parms=setup_parms(arg); if(parms->skyc.dbg){ mymkdir("%s",dirsetup); } if(!arg->force){ info2("Waiting start signal from the scheduler ...\n"); /*Failed to wait. fall back to own checking.*/ int count=0; while(scheduler_wait()&& count<60){ warning_time("failed to get reply from scheduler. retry\n"); sleep(10); count++; scheduler_start(scmd,arg->nthread,0,!arg->force); } if(count>=60){ warning_time("fall back to own checker\n"); wait_cpu(arg->nthread); } } info2("Simulation started at %s in %s.\n",myasctime(),myhostname()); free(scmd); free(arg->dirout); free(arg); THREAD_POOL_INIT(parms->skyc.nthread); /*Loads the main software*/ OMPTASK_SINGLE skysim(parms); free_parms(parms); free(dirsetup); free(dirstart); rename_file(0); scheduler_finish(0); info2("End:\t%.2f MiB\n",get_job_mem()/1024.); info2("Simulation finished at %s in %s.\n",myasctime(),myhostname()); return 0; }
static void init(const char *pid_file) { if (write_pid(pid_file)) WARNING("can't write PID file to %s: %m", pid_file); if (atexit(cleanup)) WARNING("atexit() failed: %m"); if (register_signal_handler(SIGTERM, sigterm)) WARNING("can't catch SIGTERM: %m"); }
int main(int argc, char **argv) { pid_t childpid; int listenfd, connfd; struct sockaddr_in cliaddr, servaddr; socklen_t clilen = sizeof(cliaddr); listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) err_sys("socket error"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); // bind server address if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) err_sys("bind error"); // listening on listening socket Listen(listenfd, LISTENQ); // register SIGCHLD signal handler register_signal_handler(SIGCHLD, sigchld_handler_v2); for ( ; ; ) { // accept connect request connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); if (connfd < 0) { if (errno == EINTR) continue; else err_sys("accept error"); } // create a child process if ((childpid = fork()) < 0) err_sys("fork error"); // child process if (childpid == 0) { // child closes listening socket if (close(listenfd) == -1) err_sys("child close listening socket error"); // process the request str_echo(connfd); exit(0); } // parent closes connected socket if (close(connfd) == -1) err_sys("parent close connected socket error"); } }
void NuboNoseDetectorImpl::postConstructor () { handlerOnNoseEvent = register_signal_handler (G_OBJECT (nubo_nose), "nose-event", std::function <void (GstElement *, gchar *) > (std::bind (&NuboNoseDetectorImpl::onNose, this, std::placeholders::_2) ), std::dynamic_pointer_cast<NuboNoseDetectorImpl> (shared_from_this() ) ); }
void RecorderEndpointImpl::postConstructor() { UriEndpointImpl::postConstructor(); handlerOnStateChanged = register_signal_handler (G_OBJECT (element), "state-changed", std::function <void (GstElement *, gint) > (std::bind (&RecorderEndpointImpl::onStateChanged, this, std::placeholders::_2) ), std::dynamic_pointer_cast<RecorderEndpointImpl> (shared_from_this() ) ); }
/** Initializes all ncurses' related stuff (windows, colors...). * There's no need to call 'engine_exit' */ bool engine_init() { /* signals during initialization */ block_signals(); engine_screen_init(80, 24); engine_windows_init(); engine_keymap(NULL); restore_signals(); register_signal_handler(); return true; }
void PlayerEndpointImpl::postConstructor() { UriEndpointImpl::postConstructor (); signalEOS = register_signal_handler (G_OBJECT (element), "eos", std::function <void (GstElement *) > (std::bind (&PlayerEndpointImpl::eosHandler, this) ), std::dynamic_pointer_cast<PlayerEndpointImpl> (shared_from_this() ) ); signalInvalidURI = register_signal_handler (G_OBJECT (element), "invalid-uri", std::function <void (GstElement *) > (std::bind (&PlayerEndpointImpl::invalidUri, this) ), std::dynamic_pointer_cast<PlayerEndpointImpl> (shared_from_this() ) ); signalInvalidMedia = register_signal_handler (G_OBJECT (element), "invalid-media", std::function <void (GstElement *) > (std::bind (&PlayerEndpointImpl::invalidMedia, this) ), std::dynamic_pointer_cast<PlayerEndpointImpl> (shared_from_this() ) ); }
void MediaPipelineImpl::postConstructor () { GstBus *bus; MediaObjectImpl::postConstructor (); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline) ); gst_bus_add_signal_watch (bus); busMessageHandler = register_signal_handler (G_OBJECT (bus), "message", std::function <void (GstBus *, GstMessage *) > (std::bind ( &MediaPipelineImpl::busMessage, this, std::placeholders::_2) ), std::dynamic_pointer_cast<MediaPipelineImpl> (shared_from_this() ) ); g_object_unref (bus); }
int main(int argc, char *argv[]) { atexit(free_atexit); register_signal_handler(); g_test_init(&argc, &argv, NULL); g_test_add_func("/options/no_options", test_no_options); g_test_add_func("/options/wrong_option", test_wrong_option); g_test_add_func("/options/help", test_help); g_test_add_func("/options/default_values", test_default_values); g_test_add_func("/options/wrong_port1", test_wrong_port1); g_test_add_func("/options/wrong_port2", test_wrong_port2); g_test_add_func("/options/all_values", test_all_values); g_test_add_func("/signals/sighup", test_sighup); g_test_add_func("/signals/sigterm", test_sigterm); g_test_add_func("/signals/sigint", test_sigint); g_test_add_func( "/nw/bind/test_bind_local_v4", test_bind_local_v4); #ifdef HAVE_IPV6 g_test_add_func( "/nw/bind/test_bind_local_v6", test_bind_local_v6); #endif g_test_add_func( "/nw/bind/test_bind_local_root_v4", test_bind_local_root_v4); #ifdef HAVE_IPV6 g_test_add_func( "/nw/bind/test_bind_local_root_v6", test_bind_local_root_v6); #endif g_test_add_func( "/nw/bind/test_bind_nonexisting_v4", test_bind_nonexisting_v4); #ifdef HAVE_IPV6 g_test_add_func( "/nw/bind/test_bind_nonexisting_v6", test_bind_nonexisting_v6); #endif g_test_add_func( "/nw/initialise_clients", test_initialise_clients); /* Disabled (see above) g_test_add_func( "/nw/register_server_callback", test_register_server_callback); */ return g_test_run(); }
void ZBarFilterImpl::postConstructor () { GstBus *bus; std::shared_ptr<MediaPipelineImpl> pipe; FilterImpl::postConstructor (); pipe = std::dynamic_pointer_cast<MediaPipelineImpl> (getMediaPipeline() ); bus = gst_pipeline_get_bus (GST_PIPELINE (pipe->getPipeline() ) ); bus_handler_id = register_signal_handler (G_OBJECT (bus), "message", std::function <void (GstElement *, GstMessage *) > (std::bind (&ZBarFilterImpl::busMessage, this, std::placeholders::_2) ), std::dynamic_pointer_cast<ZBarFilterImpl> (shared_from_this() ) ); g_object_unref (bus); }
int main( int argc, char * const argv[]){ int gai_error = 0; if(check_arguments(argc,argv)!=0) { exit(EXIT_FAILURE); } register_signal_handler(); memset(&hints,0,sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if( (gai_error = getaddrinfo(NULL, port, &hints, &res)) ){ print_error("getaddrinfo: %s",gai_strerror(gai_error)); exit(gai_error); } socket_fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if( socket_fd == -1 ) { print_error("%s",strerror(errno)); exit(EXIT_FAILURE); } if( bind(socket_fd,res->ai_addr, res->ai_addrlen) == -1) { print_error("%s",strerror(errno)); exit(EXIT_FAILURE); } if( listen(socket_fd, BACKLOG) == -1) { print_error("%s",strerror(errno)); exit(EXIT_FAILURE); } while(accept_connection()==0); return 0; }
/** Open a port and listen to it. Calls respond(sock) to handle data. If timeout_fun is not NULL, it will be called when 1) connection is establed/handled, 2) every timeout_sec if timeout_sec>0. This function only return at error. if localpath is not null and start with /, open the local unix port also if localpath is not null and contains ip address, only bind to that ip address */ void listen_port(uint16_t port, char *localpath, int (*responder)(int), double timeout_sec, void (*timeout_fun)(), int nodelay){ register_signal_handler(scheduler_signal_handler); fd_set read_fd_set; fd_set active_fd_set; FD_ZERO (&active_fd_set); char *ip=0; int sock_local=-1; if(localpath){ if(localpath[0]=='/'){ //also bind to AF_UNIX sock_local = bind_socket_local(localpath); if(sock_local==-1){ dbg("bind to %s failed\n", localpath); }else{ if(!listen(sock_local, 1)){ FD_SET(sock_local, &active_fd_set); }else{ perror("listen"); close(sock_local); sock_local=-1; } } }else{ ip=localpath; } } int sock = bind_socket (ip, port); if(nodelay){//turn off tcp caching. socket_tcp_nodelay(sock); } if (listen (sock, 1) < 0){ perror("listen"); exit(EXIT_FAILURE); } FD_SET (sock, &active_fd_set); while(quit_listen!=2){ if(quit_listen==1){ /* shutdown(sock, SHUT_WR) sends a FIN to the peer, therefore initialize a active close and the port will remain in TIME_WAIT state. shutdown(sock, SHUT_RD) sends nother, just mark the scoket as not readable. accept() create a new socket on the existing port. A socket is identified by client ip/port and server ip/port. It is the port that remain in TIME_WAIT state. */ //shutdown(sock, SHUT_RDWR); //shutdown(sock_local, SHUT_RDWR); /*Notice existing client to shutdown*/ for(int i=0; i<FD_SETSIZE; i++){ if(FD_ISSET(i, &active_fd_set) && i!=sock && i!=sock_local){ int cmd[3]={-1, 0, 0}; stwrite(i, cmd, 3*sizeof(int)); //We ask the client to actively close the connection //shutdown(i, SHUT_WR); } } usleep(1e5); quit_listen=2; //don't break. Listen for connection close events. } if(timeout_fun){ timeout_fun(); } struct timeval timeout; timeout.tv_sec=timeout_sec; timeout.tv_usec=(timeout_sec-timeout.tv_sec)*1e6; read_fd_set = active_fd_set; if(select(FD_SETSIZE, &read_fd_set, NULL, NULL, timeout_sec>0?&timeout:0)<0){ if(errno==EINTR){ warning("select failed: %s\n", strerror(errno)); continue; }else if(errno==EBADF){ warning("bad file descriptor: %s\n", strerror(errno)); break;//bad file descriptor }else{ warning("unknown error: %s\n", strerror(errno)); break; } } for(int i=0; i<FD_SETSIZE; i++){ if(FD_ISSET(i, &read_fd_set)){ if(i==sock){ /* Connection request on original socket. */ socklen_t size=sizeof(struct sockaddr_in); struct sockaddr_in clientname; int port2=accept(i, (struct sockaddr*)&clientname, &size); if(port2<0){ warning("accept failed: %s. close port %d\n", strerror(errno), i); FD_CLR(i, &active_fd_set); close(i); }else{ info("port %d is connected\n", port2); FD_SET(port2, &active_fd_set); } }else if(i==sock_local){ socklen_t size=sizeof(struct sockaddr_un); struct sockaddr_un clientname; int port2=accept(i, (struct sockaddr*)&clientname, &size); if(port2<0){ warning("accept failed: %s. close port %d\n", strerror(errno), i); FD_CLR(i, &active_fd_set); close(i); }else{ info("port %d is connected locally\n", port2); FD_SET(port2, &active_fd_set); } }else{ /* Data arriving on an already-connected socket. Call responder to handle. On return: negative value: Close read of socket. -1: also close the socket. */ int ans=responder(i); if(ans<0){ FD_CLR(i, &active_fd_set); if(ans==-1){ warning("close port %d\n", i); close(i); }else{ warning("ans=%d is not understood.\n", ans); } } } } } } /* Error happened. We close all connections and this server socket.*/ close(sock); close(sock_local); FD_CLR(sock, &active_fd_set); FD_CLR(sock_local, &active_fd_set); warning("listen_port exited\n"); for(int i=0; i<FD_SETSIZE; i++){ if(FD_ISSET(i, &active_fd_set)){ warning("sock %d is still connected\n", i); close(i); FD_CLR(i, &active_fd_set); } } usleep(100); sync(); }
int main(int argc, char **argv) { int ret; struct server_settings settings; // load arguments ret = parse_server_settings(argc, (char **) argv, &settings); if (is_failure(ret)) { print_usage; return ret; } int sock; SSL_CTX *ssl_ctx; SSL *ssl; pthread_t thread_id; struct client client = {&settings, NULL}; // init ssl if (is_failure(init_ssl(&ssl_ctx, NULL, settings.cert_path, settings.key_path))) goto GENERAL_CLEAN_UP; sock = create_server_socket(settings.port); printf("Listening on port %d\n", settings.port); register_signal_handler(); while (server_running) { struct sockaddr_in addr; uint len = sizeof addr; int client_sock = accept(sock, (struct sockaddr *) &addr, &len); if (client_sock < 0) { // not clean if (server_running) { error_print("Failed to accept client connection\n"); ret = ERROR_SOCKET; } break; } puts("Client connected"); if (is_failure(accept_ssl(ssl_ctx, &ssl, client_sock))) continue; // spawn thread client.ssl = ssl; if (pthread_create(&thread_id, NULL, client_handler, (void *) &client) < 0) error_print("Failed to spawn client thread\n"); } GENERAL_CLEAN_UP: puts("\nCleaning up"); if (ssl_ctx != NULL) SSL_CTX_free(ssl_ctx); ERR_free_strings(); EVP_cleanup(); return ret; }
int main(int argc, char *argv[]) { int i, purged; char* file = NULL; int fd; int pressure = 0; int opt; //signal(SIGBUS, signal_handler_sigbusy //sigaction(SIGBUS, sigaction_sigbusy, NULL); register_signal_handler(); /* Process arguments */ while ((opt = getopt(argc, argv, "p:f:"))!=-1) { switch(opt) { case 'p': pressure = atoi(optarg); break; case 'f': file = optarg; break; default: printf("Usage: %s [-p <mempressure in megs>] [-f <filename>]\n", argv[0]); printf(" -p: Amount of memory pressure to generate\n"); printf(" -f: Use a file\n"); exit(-1); } } if (file) { file = argv[1]; fd = open(file, O_RDWR); vaddr = mmap(0, FULLSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); } else { vaddr = malloc(FULLSIZE); } purged = 0; vaddr += PAGE_SIZE-1; vaddr -= (long)vaddr % PAGE_SIZE; for(i=0; i < CHUNKNUM; i++) memset(vaddr + (i*CHUNK), 'A'+i, CHUNK); for(i=0; i < CHUNKNUM; ) { mvolatile(vaddr + (i*CHUNK), CHUNK); i+=2; } // for(i=0; i < CHUNKNUM; i++) // printf("%c\n", vaddr[i*CHUNK]); generate_pressure(pressure); // for(i=0; i < CHUNKNUM; i++) // printf("%c\n", vaddr[i*CHUNK]); /*for(i=0; i < CHUNKNUM; ) { int ret; ret = mnovolatile(vaddr + (i*CHUNK), CHUNK, &purged); i+=2; }*/ if (purged) printf("Data purged!\n"); for(i=0; i < CHUNKNUM; i++) printf("%c\n", vaddr[i*CHUNK]); return 0; }
int main() { register_signal_handler(); while(1); }
/** This is the standard entrance routine to the program. It first calls setup_parms() to setup the simulation parameters and check for possible errors. It then waits for starting signal from the scheduler if in batch mode. Finally it hands the control to maos() to start the actual simulation. Call maos with overriding *.conf files or embed the overriding parameters in the command line to override the default parameters, e.g. <p><code>maos base.conf save.setup=1 'powfs.phystep=[0 100 100]'</code><p> Any duplicate parameters will override the pervious specified value. The configure file nfiraos.conf will be loaded as the master .conf unless a -c switch is used with another .conf file. For scao simulations, call maos with -c switch and the right base .conf file. <p><code>maos -c scao_ngs.conf override.conf</code><p> for scao NGS simulations <p><code>maos -c scao_lgs.conf override.conf</code><p> for scao LGS simulations. With -c switch, nfiraos.conf will not be read, instead scao_ngs.conf or scao_lgs.conf are read as the master config file. Do not specify any parameter that are not understood by the code, otherwise maos will complain and exit to prevent accidental mistakes. Generally you link the maos executable into a folder that is in your PATH evironment or into the folder where you run simulations. Other optional parameters: \verbatim -d do detach from console and not exit when logged out -s 2 -s 4 set seeds to [2 4] -n 4 launch 4 threads. -f To disable job scheduler and force proceed \endverbatim In detached mode, drawing is automatically disabled. \callgraph */ int main(int argc, const char *argv[]){ char *scmd=argv2str(argc,argv," "); ARG_T* arg=parse_args(argc,argv);/*does chdir */ if(arg->detach){ daemonize(); }else{ redirect(); } /*Launch the scheduler if it is not running and report about our process */ int ngpu; #if USE_CUDA ngpu=arg->ngpu; if(!ngpu) ngpu=0xFFFFFF; #else ngpu=0; #endif scheduler_start(scmd,NTHREAD,ngpu,!arg->force); info2("%s\n", scmd); info2("Output folder is '%s'. %d threads\n",arg->dirout, NTHREAD); maos_version(); /*setting up parameters before asking scheduler to check for any errors. */ PARMS_T *parms=setup_parms(arg->conf, arg->confcmd, arg->override); free(arg->conf); arg->conf=0; if(arg->confcmd){ remove(arg->confcmd); free(arg->confcmd); arg->confcmd=0; } info2("After setup_parms:\t %.2f MiB\n",get_job_mem()/1024.); /*register signal handler */ register_signal_handler(maos_signal_handler); if(!arg->force){ /* Ask job scheduler for permission to proceed. If no CPUs are available, will block until ones are available. if arg->force==1, will run immediately. */ info2("Waiting start signal from the scheduler ...\n"); int count=0; while(scheduler_wait()&& count<60){ /*Failed to wait. fall back to own checking.*/ warning_time("failed to get reply from scheduler. retry\n"); sleep(10); count++; scheduler_start(scmd,NTHREAD,ngpu,!arg->force); } if(count>=60){ warning_time("fall back to own checker\n"); wait_cpu(NTHREAD); } } thread_new((thread_fun)scheduler_listen, maos_daemon); setup_parms_gpu(parms, arg->gpus, arg->ngpu); if(arg->server){ while(maos_server_fd<0){ warning("Waiting for fd\n"); sleep(1); } maos_server(parms); EXIT; } free(scmd); free(arg->dirout); free(arg->gpus); free(arg); /*do not use prallel single in maos(). It causes blas to run single threaded * during preparation. Selective enable parallel for certain setup functions * that doesn't use blas*/ maos(parms); rename_file(0); scheduler_finish(0); return 0; }
int init_signal_handler(void) { register_signal_handler(PROCESS_SIGNAL_KILL, signal_kill); }
int l23_app_init(struct osmocom_ms *ms) { register_signal_handler(SS_L1CTL, &signal_cb, NULL); l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL); return layer3_init(ms); }
int main(int argc, char **argv) { int jitter_plot[101]; int latency_plot[101]; int long_index = 0; struct option long_options[] = { {"help", 0, NULL, 'h'}, {"message-size", 1, NULL, 'm'}, {"samples", 1, NULL, 's'}, {"timeout", 1, NULL, 't'} }; size_t name_arg_count; size_t name_size; char *option_string = "hm:s:t:"; int show_usage = 0; connections_established = 0; error_message = NULL; message_size = 3; program_name = argv[0]; remote_in_port = 0; remote_out_port = 0; samples = 1024; timeout = 5; for (;;) { signed char c = getopt_long(argc, argv, option_string, long_options, &long_index); switch (c) { case 'h': show_usage = 1; break; case 'm': message_size = parse_positive_number_arg(optarg, "message-size"); break; case 's': samples = parse_positive_number_arg(optarg, "samples"); break; case 't': timeout = parse_positive_number_arg(optarg, "timeout"); break; default: { char *s = "'- '"; s[2] = c; die(s, "invalid switch"); } case -1: if (show_usage) { output_usage(); exit(EXIT_SUCCESS); } goto parse_port_names; case 1: /* end of switch :) */ ; } } parse_port_names: name_arg_count = argc - optind; switch (name_arg_count) { case 2: target_in_port_name = argv[optind + 1]; target_out_port_name = argv[optind]; break; case 0: target_in_port_name = 0; target_out_port_name = 0; break; default: output_usage(); return EXIT_FAILURE; } name_size = jack_port_name_size(); alias1 = malloc(name_size * sizeof(char)); if (alias1 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto show_error; } alias2 = malloc(name_size * sizeof(char)); if (alias2 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_alias1; } latency_values = malloc(sizeof(jack_nframes_t) * samples); if (latency_values == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_alias2; } latency_time_values = malloc(sizeof(jack_time_t) * samples); if (latency_time_values == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_latency_values; } message_1 = malloc(message_size * sizeof(jack_midi_data_t)); if (message_1 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_latency_time_values; } message_2 = malloc(message_size * sizeof(jack_midi_data_t)); if (message_2 == NULL) { error_message = strerror(errno); error_source = "malloc"; goto free_message_1; } switch (message_size) { case 1: message_1[0] = 0xf6; message_2[0] = 0xfe; break; case 2: message_1[0] = 0xc0; message_1[1] = 0x00; message_2[0] = 0xd0; message_2[1] = 0x7f; break; case 3: message_1[0] = 0x80; message_1[1] = 0x00; message_1[2] = 0x00; message_2[0] = 0x90; message_2[1] = 0x7f; message_2[2] = 0x7f; break; default: message_1[0] = 0xf0; memset(message_1 + 1, 0, (message_size - 2) * sizeof(jack_midi_data_t)); message_1[message_size - 1] = 0xf7; message_2[0] = 0xf0; memset(message_2 + 1, 0x7f, (message_size - 2) * sizeof(jack_midi_data_t)); message_2[message_size - 1] = 0xf7; } client = jack_client_open(program_name, JackNullOption, NULL); if (client == NULL) { error_message = "failed to open JACK client"; error_source = "jack_client_open"; goto free_message_2; } in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); if (in_port == NULL) { error_message = "failed to register MIDI-in port"; error_source = "jack_port_register"; goto close_client; } out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); if (out_port == NULL) { error_message = "failed to register MIDI-out port"; error_source = "jack_port_register"; goto unregister_in_port; } if (jack_set_process_callback(client, handle_process, NULL)) { error_message = "failed to set process callback"; error_source = "jack_set_process_callback"; goto unregister_out_port; } if (jack_set_xrun_callback(client, handle_xrun, NULL)) { error_message = "failed to set xrun callback"; error_source = "jack_set_xrun_callback"; goto unregister_out_port; } if (jack_set_port_connect_callback(client, handle_port_connection_change, NULL)) { error_message = "failed to set port connection callback"; error_source = "jack_set_port_connect_callback"; goto unregister_out_port; } jack_on_shutdown(client, handle_shutdown, NULL); jack_set_info_function(handle_info); process_state = 0; connect_semaphore = create_semaphore(0); if (connect_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto unregister_out_port; } init_semaphore = create_semaphore(1); if (init_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto destroy_connect_semaphore;; } process_semaphore = create_semaphore(2); if (process_semaphore == NULL) { error_message = get_semaphore_error(); error_source = "create_semaphore"; goto destroy_init_semaphore; } if (jack_activate(client)) { error_message = "could not activate client"; error_source = "jack_activate"; goto destroy_process_semaphore; } if (name_arg_count) { if (jack_connect(client, jack_port_name(out_port), target_out_port_name)) { error_message = "could not connect MIDI out port"; error_source = "jack_connect"; goto deactivate_client; } if (jack_connect(client, target_in_port_name, jack_port_name(in_port))) { error_message = "could not connect MIDI in port"; error_source = "jack_connect"; goto deactivate_client; } } if (! register_signal_handler(handle_signal)) { error_message = strerror(errno); error_source = "register_signal_handler"; goto deactivate_client; } printf("Waiting for connections ...\n"); if (wait_semaphore(connect_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; } if (connections_established) { printf("Waiting for test completion ...\n\n"); if (wait_semaphore(process_semaphore, 1) == -1) { error_message = get_semaphore_error(); error_source = "wait_semaphore"; goto deactivate_client; } } if (! register_signal_handler(SIG_DFL)) { error_message = strerror(errno); error_source = "register_signal_handler"; goto deactivate_client; } if (process_state == 2) { double average_latency = ((double) total_latency) / samples; double average_latency_time = total_latency_time / samples; size_t i; double latency_plot_offset = floor(((double) lowest_latency_time) / 100.0) / 10.0; double sample_rate = (double) jack_get_sample_rate(client); jack_nframes_t total_jitter = 0; jack_time_t total_jitter_time = 0; for (i = 0; i <= 100; i++) { jitter_plot[i] = 0; latency_plot[i] = 0; } for (i = 0; i < samples; i++) { double latency_time_value = (double) latency_time_values[i]; double latency_plot_time = (latency_time_value / 1000.0) - latency_plot_offset; double jitter_time = ABS(average_latency_time - latency_time_value); if (latency_plot_time >= 10.0) { (latency_plot[100])++; } else { (latency_plot[(int) (latency_plot_time * 10.0)])++; } if (jitter_time >= 10000.0) { (jitter_plot[100])++; } else { (jitter_plot[(int) (jitter_time / 100.0)])++; } total_jitter += ABS(average_latency - ((double) latency_values[i])); total_jitter_time += jitter_time; } printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n" "Average latency: %.2f ms (%.2f frames)\n" "Lowest latency: %.2f ms (%u frames)\n" "Highest latency: %.2f ms (%u frames)\n" "Peak MIDI jitter: %.2f ms (%u frames)\n" "Average MIDI jitter: %.2f ms (%.2f frames)\n", (out_latency_range.min / sample_rate) * 1000.0, (out_latency_range.max / sample_rate) * 1000.0, out_latency_range.min, out_latency_range.max, (in_latency_range.min / sample_rate) * 1000.0, (in_latency_range.max / sample_rate) * 1000.0, in_latency_range.min, in_latency_range.max, average_latency_time / 1000.0, average_latency, lowest_latency_time / 1000.0, lowest_latency, highest_latency_time / 1000.0, highest_latency, (highest_latency_time - lowest_latency_time) / 1000.0, highest_latency - lowest_latency, (total_jitter_time / 1000.0) / samples, ((double) total_jitter) / samples); printf("\nJitter Plot:\n"); for (i = 0; i < 100; i++) { if (jitter_plot[i]) { printf("%.1f - %.1f ms: %d\n", ((float) i) / 10.0, ((float) (i + 1)) / 10.0, jitter_plot[i]); } } if (jitter_plot[100]) { printf(" > 10 ms: %d\n", jitter_plot[100]); } printf("\nLatency Plot:\n"); for (i = 0; i < 100; i++) { if (latency_plot[i]) { printf("%.1f - %.1f ms: %d\n", latency_plot_offset + (((float) i) / 10.0), latency_plot_offset + (((float) (i + 1)) / 10.0), latency_plot[i]); } } if (latency_plot[100]) { printf(" > %.1f ms: %d\n", latency_plot_offset + 10.0, latency_plot[100]); } } deactivate_client: jack_deactivate(client); printf("\nMessages sent: %d\nMessages received: %d\n", messages_sent, messages_received); if (unexpected_messages) { printf("Unexpected messages received: %d\n", unexpected_messages); } if (xrun_count) { printf("Xruns: %d\n", xrun_count); } destroy_process_semaphore: destroy_semaphore(process_semaphore, 2); destroy_init_semaphore: destroy_semaphore(init_semaphore, 1); destroy_connect_semaphore: destroy_semaphore(connect_semaphore, 0); unregister_out_port: jack_port_unregister(client, out_port); unregister_in_port: jack_port_unregister(client, in_port); close_client: jack_client_close(client); free_message_2: free(message_2); free_message_1: free(message_1); free_latency_time_values: free(latency_time_values); free_latency_values: free(latency_values); free_alias2: free(alias2); free_alias1: free(alias1); if (error_message != NULL) { show_error: output_error(error_source, error_message); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }