int loop(void){ int i; int status = 0; struct emwin_server *es; es = get_next_server(); if(es == NULL){ status = 1; log_errx("No servers available."); log_info("Waiting %d seconds.", g.retrysleep); for(i = 0; i <= g.retrysleep; ++i){ sleep(1); if(get_quit_flag() != 0) break; } log_info("Trying server list again."); }else if(es->fd == -1){ if(es->gai_code != 0){ log_errx("Cannot open connection to %s. %s", es->ip, gai_strerror(es->gai_code)); }else{ log_err2("Cannot open connection to", es->ip); } status = 1; }else if(es->fd == -2){ if(server_type_serial_device(es)) log_errx("Cannot configure or synchronize %s:%s", es->ip, es->port); else log_errx("Could not get packet from %s", es->ip); status = 1; }else{ log_info("Connected to %s @ %s", es->ip, es->port); } while((status == 0) && (get_quit_flag() == 0)){ if(g.f_server_enabled == 1) server_loop(); status = process_packets(es); periodic(); if(get_reload_servers_list_flag()) reload_servers_list(); if(get_send_bbclientid_flag()) bb_send_clientid(es); } if(get_quit_flag() != 0) log_info("Closing processor."); return(status); }
static void *slavenet_main(void *arg){ struct slave_element_st *slave = (struct slave_element_st*)arg; int status = 0; pthread_cleanup_push(slavenet_cleanup_info, arg); pthread_cleanup_push(slavenet_try_close, arg); status = slavenet_init_info(slave); if(status != 0) set_quit_flag(); else{ status = slavenet_open(slave); /* * If slavenet_open() returns 2, it is a configuration error and we quit * the application. Otherwise we assume that, if there is an error, * it is a temporary situation and try to reopen the connection in * the loop. */ if(status == 2) set_quit_flag(); } if(status == 0) slave_stats_connect(slave); while(get_quit_flag() == 0){ /* * If the slave_fd is -1 it means that the socket was closed * due to a reading error. It could be a real error, or the server * not sending anything within the timeout limit and the like. * reopen() waits some time and tries to reopen it. */ if(slave->slave_fd == -1){ log_errx("Closed connection to %s. Reconnecting.", slave->mastername); status = slavenet_reopen(slave); if(slave->slave_fd != -1) slave_stats_connect(slave); } if(slave->slave_fd != -1){ status = slavenet_loop(slave); /* * When this function returns 1 it means there was a connection error. * When it returns 2 it is a processing error and there is no need * to close the connection. */ if(status == 1) status = slavenet_close(slave); } } pthread_cleanup_pop(1); pthread_cleanup_pop(1); return(NULL); }
static void *client_thread_main(void *arg){ /* * The *arg is a private copy of the ce. This function must * free(ce) it when it is finished, but it must _not_ try to * delete anything else from the ce. * We used to set the cancellation state to DISABLED and then renabled * after the loop in the loop, to avoid cancelling the thread while * it holds a mutex locked. But this not appropriate if we let the * g.client_queue_read_timeout_ms be a configurable parameter: the user * can set this very high, and the thread would not be canceled until * that timer expires. [The alternative would be to write a wrapper * over connqueue_rcv() that disbales the cancellation and calls * connqueue_rcv() with a short (i.e., 1 second) wait time * and retries any number of times.] * * See cleanup(). */ /* int cancel_state; */ /* int status = 0; */ struct conn_element_st *ce = (struct conn_element_st*)arg; pthread_cleanup_push(cleanup, arg); while((get_quit_flag() == 0) && (conn_element_get_exit_flag(ce) == 0)){ pthread_testcancel(); /* * status = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); */ periodic(ce); loop(ce); /* * status = pthread_setcancelstate(cancel_state, &cancel_state); */ } pthread_cleanup_pop(1); return(NULL); }
static int send_client(struct conn_element_st *ce, void *data, uint32_t data_size){ int status = 0; int count = 0; do { if(conn_element_get_fd(ce) != -1) status = send_client1(ce, data, data_size); if(conn_element_get_fd(ce) != -1) return(status); /* fd == -1 */ if(count == ce->reconnect_wait_sleep_retry) break; else status = wait_client_reconnection(ce); if(status != 0) ++count; } while((get_quit_flag() == 0) && (conn_element_get_exit_flag(ce) == 0)); /* * If we are here then the connection had to be closed by one of the * send_xxx_client(), and the client has not reconnected within * the time limit set by the reconnect_wait_sleep_secs and * reconnect_wait_sleep_retry options. * * The caller should set the finished flag so that the thread exits * and the main thread deletes this entry. */ return(status); }
int main(void){ int status; int gai_code; gserverfd = tcp_server_open_conn(NULL, NBSP_PORT, 5, NULL, &gai_code); if(gserverfd == -1){ if(gai_code != 0) errx(1, "tcp_server. %s", gai_strerror(gai_code)); else err(1, "server_open_nconn()"); } status = init_conn_table(); while((status == 0) && (get_quit_flag() == 0)){ status = loop(); } free_conn_table(); close(gserverfd); return(0); }
int main(int argc, char **argv){ int status = 0; init_globals(); atexit(cleanup); /* * PROBLEM * We used to call init_signals() only after init_daemon(). But in * that case, when started with -F or -D -D, the signals are * not caught in Linunx and OSX (they are caught in FreeBSD). nbspd and * npemwind die, but leave the pid file and the web server. * [It seems that the signals are not blocked in the main thread as * the code in signal.c should ensure.] * Adding this call here * * status = init_signals(); * * makes OSX and Linux respond well when the daemon is run in the foreground. * If the call is made after the tcl configure(), the problem repeats; * it has to be before the configure() function. * * The problem is that in FreeBSD-7.1, when init_signals() is called here, * then no threads are spawned afterwards. * * The solution was to split init_signals() in two parts, one that * block the signals and the other spawns the thread. I don't fully * understand what in tcl is causing this (Fri Mar 13 11:43:09 AST 2009). */ status = init_signals_block(); if(status == 0){ /* * This will configure it with the default configuration * file, if it exists. * * This note and Tcl... code line is taken from the nbsp source code. * [First initialize the tcl library once and for all. It was not * necessary to call this in unix, but cygwin needs it or EvalFile * seg faults.] */ Tcl_FindExecutable(argv[0]); status = configure(); } if(status == 0) status = parse_args(argc, argv); if(status == 0){ if(g.configfile != NULL){ /* * This will reconfigure it with the user-supplied config file */ status = configure(); } } /* * if [-C] was given, print the configuration and exit. */ if(status == 0){ if(g.option_C == 1){ print_confoptions(); return(0); } } if(status == 0) status = validate_configuration(); /* * user and group are configurable so this must be done after reading * configuration options. */ if(status == 0) status = drop_privs(); if(status == 0) status = init_server_list(); if(status == 0) status = init_directories(); /* * The last configuration step, just before becoming a daemon. */ if(status == 0) status = exec_startscript(); if((status == 0) && (g.f_ndaemon == 0)) status = init_daemon(); set_log_debug(g.f_debug); set_log_verbose(g.f_verbose); if(status == 0) status = init_signals_thread(); /* * This has to be done after daemon() so that the lock file contains the * daemon's pid, not the starting program's. */ if(status == 0) status = init_lock(); /* * There are no shared queues in npemwin, otherwise the initialization * would go here. * * if(status == 0) * status = init_queues(); */ if(status == 0){ if(g.serverprotocol != PROTOCOL_NONE) { g.f_server_enabled = 1; status = init_server(); } } if(status == 0){ if(g.httpd_enable > 0){ status = spawn_httpd_server(); } } if(status == 0){ if(g.bbserver_enable > 0){ status = spawn_bbregistrar(); } } if(status == 0) status = init_emwin_qfiles(); if(status == 0) init_periodic(); /* * If there are initialization errors, ask all threads to quit. */ if(status != 0) set_quit_flag(); while(get_quit_flag() == 0){ status = loop(); } if(status != 0) status = EXIT_FAILURE; return(status); }