static void smsboxc_run(void *arg) { int fd; int port; gwlist_add_producer(flow_threads); gwthread_wakeup(MAIN_THREAD_ID); port = (int) *((long *)arg); fd = make_server_socket(port, NULL); /* XXX add interface_name if required */ if (fd < 0) { panic(0, "Could not open smsbox port %d", port); } /* * infinitely wait for new connections; * to shut down the system, SIGTERM is send and then * select drops with error, so we can check the status */ wait_for_connections(fd, run_smsbox, incoming_sms, smsbox_port_ssl); gwlist_remove_producer(smsbox_list); /* continue avalanche */ gwlist_remove_producer(outgoing_sms); /* all connections do the same, so that all must remove() before it * is completely over */ while(gwlist_wait_until_nonempty(smsbox_list) == 1) gwthread_sleep(1.0); /* close listen socket */ close(fd); gwthread_wakeup(sms_dequeue_thread); gwthread_join(sms_dequeue_thread); gwlist_destroy(smsbox_list, NULL); smsbox_list = NULL; gw_rwlock_destroy(smsbox_list_rwlock); smsbox_list_rwlock = NULL; /* destroy things related to smsbox routing */ dict_destroy(smsbox_by_id); smsbox_by_id = NULL; dict_destroy(smsbox_by_smsc); smsbox_by_smsc = NULL; dict_destroy(smsbox_by_receiver); smsbox_by_receiver = NULL; dict_destroy(smsbox_by_smsc_receiver); smsbox_by_smsc_receiver = NULL; gwlist_remove_producer(flow_threads); }
static void run_wapbox(void *arg) { Boxc *newconn; List *newlist; long sender; gwlist_add_producer(flow_threads); newconn = arg; newconn->is_wap = 1; /* * create a new incoming list for just that box, * and add it to list of list pointers, so we can start * to route messages to it. */ debug("bb", 0, "setting up systems for new wapbox"); newlist = gwlist_create(); /* this is released by the sender/receiver if it exits */ gwlist_add_producer(newlist); newconn->incoming = newlist; newconn->retry = incoming_wdp; newconn->outgoing = outgoing_wdp; sender = gwthread_create(boxc_sender, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); goto cleanup; } gwlist_append(wapbox_list, newconn); gwlist_add_producer(newconn->outgoing); boxc_receiver(newconn); /* cleanup after receiver has exited */ gwlist_remove_producer(newconn->outgoing); gwlist_lock(wapbox_list); gwlist_delete_equal(wapbox_list, newconn); gwlist_unlock(wapbox_list); while (gwlist_producer_count(newlist) > 0) gwlist_remove_producer(newlist); newconn->alive = 0; gwthread_join(sender); cleanup: gw_assert(gwlist_len(newlist) == 0); gwlist_destroy(newlist, NULL); boxc_destroy(newconn); gwlist_remove_producer(flow_threads); }
static void set_shutdown_status(void) { sig_atomic_t old = bb_status; bb_status = BB_SHUTDOWN; if (old == BB_SUSPENDED) gwlist_remove_producer(suspended); if (old == BB_SUSPENDED || old == BB_ISOLATED) gwlist_remove_producer(isolated); }
/* * this thread listens to incoming_wdp list * and then routs messages to proper wapbox */ static void wdp_to_wapboxes(void *arg) { List *route_info; AddrPar *ap; Boxc *conn; Msg *msg; int i; gwlist_add_producer(flow_threads); gwlist_add_producer(wapbox_list); route_info = gwlist_create(); while(bb_status != BB_DEAD) { gwlist_consume(suspended); /* block here if suspended */ if ((msg = gwlist_consume(incoming_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); conn = route_msg(route_info, msg); if (conn == NULL) { warning(0, "Cannot route message, discard it"); msg_destroy(msg); continue; } gwlist_produce(conn->incoming, msg); } debug("bb", 0, "wdp_to_wapboxes: destroying lists"); while((ap = gwlist_extract_first(route_info)) != NULL) ap_destroy(ap); gw_assert(gwlist_len(route_info) == 0); gwlist_destroy(route_info, NULL); gwlist_lock(wapbox_list); for(i=0; i < gwlist_len(wapbox_list); i++) { conn = gwlist_get(wapbox_list, i); gwlist_remove_producer(conn->incoming); conn->alive = 0; } gwlist_unlock(wapbox_list); gwlist_remove_producer(wapbox_list); gwlist_remove_producer(flow_threads); }
static void sql_list(Boxc *boxc) { Msg *msg; List *qlist, *save_list; qlist = gwlist_create(); gwlist_add_producer(qlist); save_list = gwlist_create(); gwlist_add_producer(save_list); while (sqlbox_status == SQL_RUNNING && boxc->alive) { if ( gw_sql_fetch_msg_list(qlist, limit_per_cycle) > 0 ) { while((gwlist_len(qlist)>0) && ((msg = gwlist_consume(qlist)) != NULL )) { if (charset_processing(msg) == -1) { error(0, "Could not charset process message, dropping it!"); msg_destroy(msg); continue; } if (global_sender != NULL && (msg->sms.sender == NULL || octstr_len(msg->sms.sender) == 0)) { msg->sms.sender = octstr_duplicate(global_sender); } /* convert validity and deferred to unix timestamp */ if (msg->sms.validity != SMS_PARAM_UNDEFINED) msg->sms.validity = time(NULL) + msg->sms.validity * 60; if (msg->sms.deferred != SMS_PARAM_UNDEFINED) msg->sms.deferred = time(NULL) + msg->sms.deferred * 60; send_msg(boxc->bearerbox_connection, boxc, msg); /* convert validity & deferred back to minutes */ if (save_mt && msg->sms.validity != SMS_PARAM_UNDEFINED) msg->sms.validity = (msg->sms.validity - time(NULL))/60; if (save_mt && msg->sms.deferred != SMS_PARAM_UNDEFINED) msg->sms.deferred = (msg->sms.deferred - time(NULL))/60; gwlist_produce(save_list, msg); } /* save_list also deletes and destroys messages */ gw_sql_save_list(save_list, octstr_imm("MT"), save_mt); } else { gwthread_sleep(SLEEP_BETWEEN_EMPTY_SELECTS); } } gwlist_remove_producer(qlist); gwlist_remove_producer(save_list); gwlist_destroy(qlist, msg_destroy_item); gwlist_destroy(save_list, msg_destroy_item); }
static void udp_sender(void *arg) { Msg *msg; Udpc *conn = arg; gwlist_add_producer(flow_threads); while (1) { if ((msg = gwlist_consume(conn->outgoing_list)) == NULL) break; info(0, "sending datagram <%s:%ld> -> <%s:%ld>", octstr_get_cstr(msg->wdp_datagram.source_address), msg->wdp_datagram.source_port, octstr_get_cstr(msg->wdp_datagram.destination_address), msg->wdp_datagram.destination_port); dump(msg); if (send_udp(conn->fd, msg) == -1) { msg_destroy(msg); continue; } counter_increase(outgoing_wdp_counter); msg_destroy(msg); } gwthread_join(conn->receiver); udpc_destroy(conn); gwlist_remove_producer(flow_threads); }
static void udp_sender(void *arg) { Msg *msg; Udpc *conn = arg; gwlist_add_producer(flow_threads); while(bb_status != BB_DEAD) { gwlist_consume(suspended); /* block here if suspended */ if ((msg = gwlist_consume(conn->outgoing_list)) == NULL) break; debug("bb.udp", 0, "udp: sending message"); if (send_udp(conn->fd, msg) == -1) /* ok, we failed... tough * XXX log the message or something like that... but this * is not as fatal as it is with SMS-messages... */ { msg_destroy(msg); continue; } counter_increase(outgoing_wdp_counter); msg_destroy(msg); } gwthread_join(conn->receiver); udpc_destroy(conn); gwlist_remove_producer(flow_threads); }
static void wdp_router(void *arg) { Msg *msg; gwlist_add_producer(flow_threads); while (bb_status != BB_DEAD) { if ((msg = gwlist_consume(outgoing_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); /* if (msg->list == sms) smsc_addwdp(msg); else */ udp_addwdp(msg); } udp_die(); /* smsc_endwdp(); */ gwlist_remove_producer(flow_threads); }
int bb_resume(void) { mutex_lock(status_mutex); if (bb_status != BB_SUSPENDED && bb_status != BB_ISOLATED) { mutex_unlock(status_mutex); return -1; } if (bb_status == BB_SUSPENDED) gwlist_remove_producer(suspended); smsc2_resume(0); bb_status = BB_RUNNING; gwlist_remove_producer(isolated); mutex_unlock(status_mutex); return 0; }
static int httpsmsc_shutdown(SMSCConn *conn, int finish_sending) { ConnData *conndata = conn->data; if (conndata == NULL) return 0; debug("httpsmsc_shutdown", 0, "HTTP[%s]: Shutting down", octstr_get_cstr(conn->id)); mutex_lock(conn->flow_mutex); conn->why_killed = SMSCCONN_KILLED_SHUTDOWN; conndata->shutdown = 1; if (conndata->port > 0) http_close_port(conndata->port); gwlist_remove_producer(conndata->msg_to_send); if (conndata->receive_thread != -1) gwthread_wakeup(conndata->receive_thread); if (conndata->sender_thread != -1) gwthread_wakeup(conndata->sender_thread); mutex_unlock(conn->flow_mutex); return 0; }
static void wrapper_start(SMSCConn *conn) { SmscWrapper *wrap = conn->data; debug("smscconn", 0, "Starting wrapper"); gwlist_remove_producer(wrap->stopped); }
int udp_shutdown(void) { if (!udp_running) return -1; debug("bb.thread", 0, "udp_shutdown: Starting avalanche"); gwlist_remove_producer(incoming_wdp); return 0; }
void gw_timer_elapsed_destroy(Timer *timer) { if (timer == NULL) return; gw_timer_elapsed_stop(timer); if (timer->output != NULL) gwlist_remove_producer(timer->output); gw_free(timer); }
void wap_push_ota_shutdown(void) { gw_assert(run_status == running); run_status = terminating; gwlist_remove_producer(ota_queue); gwthread_join_every(main_thread); gwlist_destroy(ota_queue, wap_event_destroy_item); bearerbox_address_destroy(bearerbox); }
void gwtimer_destroy(Timer *timer) { gw_assert(initialized); if (timer == NULL) return; gwtimer_stop(timer); gwlist_remove_producer(timer->output); wap_event_destroy(timer->event); gw_free(timer); }
static void wapboxc_run(void *arg) { int fd, port; gwlist_add_producer(flow_threads); gwthread_wakeup(MAIN_THREAD_ID); port = (int) *((long*)arg); fd = make_server_socket(port, NULL); /* XXX add interface_name if required */ if (fd < 0) { panic(0, "Could not open wapbox port %d", port); } wait_for_connections(fd, run_wapbox, incoming_wdp, wapbox_port_ssl); /* continue avalanche */ gwlist_remove_producer(outgoing_wdp); /* wait for all connections to die and then remove list */ while(gwlist_wait_until_nonempty(wapbox_list) == 1) gwthread_sleep(1.0); /* wait for wdp_to_wapboxes to exit */ while(gwlist_consume(wapbox_list)!=NULL) ; /* close listen socket */ close(fd); gwlist_destroy(wapbox_list, NULL); wapbox_list = NULL; gwlist_remove_producer(flow_threads); }
static void producer(void *arg) { long i, index; long id; struct producer_info *info; info = arg; id = gwthread_self(); index = info->start_index; for (i = 0; i < NUM_ITEMS_PER_PRODUCER; ++i, ++index) gwlist_produce(info->list, new_item(id, i, index)); gwlist_remove_producer(info->list); }
void wsp_push_client_shutdown(void) { gw_assert(push_client_run_status == running); push_client_run_status = terminating; gwlist_remove_producer(push_client_queue); gwthread_join_every(main_thread); debug("wap.wsp", 0, "wsp_push_client_shutdown: %ld push client machines" "left", gwlist_len(push_client_machines)); gwlist_destroy(push_client_machines, push_client_machine_destroy); gwlist_destroy(push_client_queue, wap_event_destroy_item); counter_destroy(push_client_machine_id_counter); }
void dbpool_destroy(DBPool *p) { if (p == NULL) return; /* nothing todo here */ gw_assert(p->pool != NULL && p->db_ops != NULL); gwlist_remove_producer(p->pool); gwlist_destroy(p->pool, (void*) dbpool_conn_destroy); p->db_ops->conf_destroy(p->conf); gw_free(p); }
static void boxc_sender(void *arg) { Msg *msg; Boxc *conn = arg; gwlist_add_producer(flow_threads); while (bb_status != BB_DEAD && conn->alive) { /* * Make sure there's no data left in the outgoing connection before * doing the potentially blocking gwlist_consume()s */ conn_flush(conn->conn); gwlist_consume(suspended); /* block here if suspended */ if ((msg = gwlist_consume(conn->incoming)) == NULL) { /* tell sms/wapbox to die */ msg = msg_create(admin); msg->admin.command = restart ? cmd_restart : cmd_shutdown; send_msg(conn, msg); msg_destroy(msg); break; } if (msg_type(msg) == heartbeat) { debug("bb.boxc", 0, "boxc_sender: catch an heartbeat - we are alive"); msg_destroy(msg); continue; } boxc_sent_push(conn, msg); if (!conn->alive || send_msg(conn, msg) == -1) { /* we got message here */ boxc_sent_pop(conn, msg, NULL); gwlist_produce(conn->retry, msg); break; } msg_destroy(msg); debug("bb.boxc", 0, "boxc_sender: sent message to <%s>", octstr_get_cstr(conn->client_ip)); } /* the client closes the connection, after that die in receiver */ /* conn->alive = 0; */ /* set conn to unroutable */ conn->routable = 0; gwlist_remove_producer(flow_threads); }
void wsp_session_shutdown(void) { gw_assert(run_status == running); run_status = terminating; gwlist_remove_producer(queue); gwthread_join_every(main_thread); gwlist_destroy(queue, wap_event_destroy_item); debug("wap.wsp", 0, "WSP: %ld session machines left.", gwlist_len(session_machines)); gwlist_destroy(session_machines, machine_destroy); counter_destroy(session_id_counter); wsp_strings_shutdown(); }
void wtp_initiator_shutdown(void) { gw_assert(initiator_run_status == running); initiator_run_status = terminating; gwlist_remove_producer(queue); gwthread_join_every(main_thread); debug("wap.wtp", 0, "wtp_initiator_shutdown: %ld init_machines left", gwlist_len(init_machines)); gwlist_destroy(init_machines, init_machine_destroy); gwlist_destroy(queue, wap_event_destroy_item); counter_destroy(init_machine_id_counter); timers_shutdown(); }
int bb_isolate(void) { mutex_lock(status_mutex); if (bb_status != BB_RUNNING && bb_status != BB_SUSPENDED) { mutex_unlock(status_mutex); return -1; } if (bb_status == BB_RUNNING) { smsc2_suspend(); gwlist_add_producer(isolated); } else gwlist_remove_producer(suspended); bb_status = BB_ISOLATED; mutex_unlock(status_mutex); return 0; }
static int wrapper_shutdown(SMSCConn *conn, int finish_sending) { SmscWrapper *wrap = conn->data; debug("bb.sms", 0, "Shutting down SMSCConn %s, %s", octstr_get_cstr(conn->name), finish_sending ? "slow" : "instant"); if (finish_sending == 0) { Msg *msg; while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } } gwlist_remove_producer(wrap->outgoing_queue); gwthread_wakeup(wrap->sender_thread); gwthread_wakeup(wrap->receiver_thread); return 0; }
void wtls_shutdown(void) { /* Make sure that we're actually running; if so, then prepare for termination */ gw_assert(wtls_run_status == running); wtls_run_status = terminating; gwlist_remove_producer(wtls_queue); gwthread_join_every(main_thread); /* Print out a friendly message stating that we're going to die */ debug("wap.wtls", 0, "wtls_shutdown: %ld wtls machines left", gwlist_len(wtls_machines)); /* And clean up nicely after ourselves */ gwlist_destroy(wtls_machines, wtls_machine_destroy); gwlist_destroy(wtls_queue, wap_event_destroy_item); counter_destroy(wtls_machine_id_counter); }
static int udp_die(void) { Udpc *udpc; if (!udp_running) return -1; /* * remove producers from all outgoing lists. */ debug("bb.udp", 0, "udp_die: removing producers from udp-lists"); while ((udpc = gwlist_consume(udpc_list)) != NULL) { gwlist_remove_producer(udpc->outgoing_list); } gwlist_destroy(udpc_list, NULL); udp_running = 0; return 0; }
static void service_router(void *arg) { Msg *msg; gwlist_add_producer(flow_threads); while (1) { if ((msg = gwlist_consume(incoming_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); udp_addwdp_from_client(msg); } udp_die(); gwlist_remove_producer(flow_threads); }
int gw_rwlock_unlock(RWLock *lock) { int ret = 0; gw_assert(lock != NULL); #ifdef HAVE_PTHREAD_RWLOCK ret = pthread_rwlock_unlock(&lock->rwlock); if (ret != 0) panic(ret, "Error while gw_rwlock_unlock."); #else RWDEBUG("", 0, "------------ gw_rwlock_unlock(%p) ----------", lock); if (lock->writer == gwthread_self()) { lock->writer = -1; gwlist_unlock(lock->rwlock); } else gwlist_remove_producer(lock->rwlock); #endif return ret; }
static int store_spool_load(void(*receive_msg)(Msg*)) { int rc; /* check if we are active */ if (spool == NULL) return 0; /* sanity check */ if (receive_msg == NULL) return -1; rc = for_each_file(spool, 0, dispatch, receive_msg); info(0, "Loaded %ld messages from store.", counter_value(counter)); /* allow using of storage */ gwlist_remove_producer(loaded); return rc; }
void alog(const char *fmt, ...) { char buf[FORMAT_SIZE + 1]; va_list args; if (file == NULL) return; format(buf, fmt); va_start(args, fmt); gwlist_lock(writers); gwlist_add_producer(writers); gwlist_unlock(writers); vfprintf(file, buf, args); fflush(file); gwlist_remove_producer(writers); va_end(args); }