static void sql_to_bearerbox(void *arg) { Boxc *boxc; boxc = gw_malloc(sizeof(Boxc)); boxc->bearerbox_connection = connect_to_bearerbox_real(bearerbox_host, bearerbox_port, bearerbox_port_ssl, NULL /* bb_our_host */); boxc->smsbox_connection = NULL; boxc->client_ip = NULL; boxc->alive = 1; boxc->connect_time = time(NULL); boxc->boxc_id = octstr_duplicate(sqlbox_id); if (boxc->bearerbox_connection == NULL) { boxc_destroy(boxc); return; } gwthread_create(bearerbox_to_sql, boxc); identify_to_bearerbox(boxc); if (gw_sql_fetch_msg_list == NULL || gw_sql_save_list == NULL || limit_per_cycle <= 1) { sql_single(boxc); } else { sql_list(boxc); } boxc_destroy(boxc); }
static void run_sqlbox(void *arg) { int fd; Boxc *newconn; long sender; fd = (int)arg; newconn = accept_boxc(fd, sqlbox_port_ssl); if (newconn == NULL) { panic(0, "Socket accept failed"); return; } newconn->bearerbox_connection = connect_to_bearerbox_real(bearerbox_host, bearerbox_port, bearerbox_port_ssl, NULL /* bb_our_host */); /* XXX add our_host if required */ sender = gwthread_create(bearerbox_to_smsbox, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); //goto cleanup; } smsbox_to_bearerbox(newconn); gwthread_join(sender); boxc_destroy(newconn); }
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 run_smsbox(void *arg) { Boxc *newconn; long sender; Msg *msg; List *keys; Octstr *key; gwlist_add_producer(flow_threads); newconn = arg; newconn->incoming = gwlist_create(); gwlist_add_producer(newconn->incoming); newconn->retry = incoming_sms; newconn->outgoing = outgoing_sms; newconn->sent = dict_create(smsbox_max_pending, NULL); newconn->pending = semaphore_create(smsbox_max_pending); 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; } /* * We register newconn in the smsbox_list here but mark newconn as routable * after identification or first message received from smsbox. So we can avoid * a race condition for routable smsboxes (otherwise between startup and * registration we will forward some messages to smsbox). */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_append(smsbox_list, newconn); gw_rwlock_unlock(smsbox_list_rwlock); gwlist_add_producer(newconn->outgoing); boxc_receiver(newconn); gwlist_remove_producer(newconn->outgoing); /* remove us from smsbox routing list */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_delete_equal(smsbox_list, newconn); if (newconn->boxc_id) { dict_remove(smsbox_by_id, newconn->boxc_id); } gw_rwlock_unlock(smsbox_list_rwlock); /* * check if we in the shutdown phase and sms dequeueing thread * has removed the producer already */ if (gwlist_producer_count(newconn->incoming) > 0) gwlist_remove_producer(newconn->incoming); /* check if we are still waiting for ack's and semaphore locked */ if (dict_key_count(newconn->sent) >= smsbox_max_pending) semaphore_up(newconn->pending); /* allow sender to go down */ gwthread_join(sender); /* put not acked msgs into incoming queue */ keys = dict_keys(newconn->sent); while((key = gwlist_extract_first(keys)) != NULL) { msg = dict_remove(newconn->sent, key); gwlist_produce(incoming_sms, msg); octstr_destroy(key); } gw_assert(gwlist_len(keys) == 0); gwlist_destroy(keys, octstr_destroy_item); /* clear our send queue */ while((msg = gwlist_extract_first(newconn->incoming)) != NULL) { gwlist_produce(incoming_sms, msg); } cleanup: gw_assert(gwlist_len(newconn->incoming) == 0); gwlist_destroy(newconn->incoming, NULL); gw_assert(dict_key_count(newconn->sent) == 0); dict_destroy(newconn->sent); semaphore_destroy(newconn->pending); boxc_destroy(newconn); /* wakeup the dequeueing thread */ gwthread_wakeup(sms_dequeue_thread); gwlist_remove_producer(flow_threads); }