Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

list.c File Reference

#include "gw-config.h"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "gwassert.h"
#include "list.h"
#include "log.h"
#include "thread.h"
#include "gwmem.h"

Include dependency graph for list.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  List

Defines

#define INDEX(list, i)   (((list)->start + i) % (list)->tab_size)
#define GET(list, i)   ((list)->tab[INDEX(list, i)])

Functions

long gwthread_self (void)
void lock (List *list)
void unlock (List *list)
void make_bigger (List *list, long items)
void delete_items_from_list (List *list, long pos, long count)
Listgwlist_create_real (void)
void gwlist_destroy (List *list, gwlist_item_destructor_t *destructor)
long gwlist_len (List *list)
void gwlist_append (List *list, void *item)
void gwlist_append_unique (List *list, void *item, int(*cmp)(void *, void *))
void gwlist_insert (List *list, long pos, void *item)
void gwlist_delete (List *list, long pos, long count)
long gwlist_delete_matching (List *list, void *pat, gwlist_item_matches_t *matches)
long gwlist_delete_equal (List *list, void *item)
void * gwlist_get (List *list, long pos)
void * gwlist_extract_first (List *list)
Listgwlist_extract_matching (List *list, void *pat, gwlist_item_matches_t *cmp)
void gwlist_lock (List *list)
void gwlist_unlock (List *list)
int gwlist_wait_until_nonempty (List *list)
void gwlist_add_producer (List *list)
int gwlist_producer_count (List *list)
void gwlist_remove_producer (List *list)
void gwlist_produce (List *list, void *item)
void * gwlist_consume (List *list)
void * gwlist_timed_consume (List *list, long sec)
void * gwlist_search (List *list, void *pattern, int(*cmp)(void *, void *))
Listgwlist_search_all (List *list, void *pattern, int(*cmp)(void *, void *))
void gwlist_sort (List *list, int(*cmp)(const void *, const void *))


Define Documentation

#define GET list,
 )     ((list)->tab[INDEX(list, i)])
 

Definition at line 115 of file list.c.

Referenced by gwlist_append_unique(), gwlist_consume(), gwlist_delete_equal(), gwlist_delete_matching(), gwlist_extract_first(), gwlist_extract_matching(), gwlist_get(), gwlist_insert(), gwlist_search(), gwlist_search_all(), gwlist_sort(), and gwlist_timed_consume().

#define INDEX list,
 )     (((list)->start + i) % (list)->tab_size)
 

Definition at line 114 of file list.c.

Referenced by delete_items_from_list(), gwlist_append(), gwlist_append_unique(), and gwlist_insert().


Function Documentation

void delete_items_from_list List list,
long  pos,
long  count
[static]
 

Definition at line 629 of file list.c.

References gw_assert, INDEX, List::len, List::start, List::tab, and List::tab_size.

Referenced by gwlist_consume(), gwlist_delete(), gwlist_delete_equal(), gwlist_delete_matching(), gwlist_extract_first(), gwlist_extract_matching(), and gwlist_timed_consume().

00630 {
00631     long i, from, to;
00632 
00633     gw_assert(pos >= 0);
00634     gw_assert(pos < list->len);
00635     gw_assert(count >= 0);
00636     gw_assert(pos + count <= list->len);
00637 
00638     /*
00639      * There are four cases:
00640      *
00641      * Case 1: Deletion at beginning of list. Just move start
00642      * marker forwards (wrapping it at end of array). No need
00643      * to move any items.
00644      *
00645      * Case 2: Deletion at end of list. Just shorten the length
00646      * of the list. No need to move any items.
00647      *
00648      * Case 3: Deletion in the middle so that the list does not
00649      * wrap in the array. Move remaining items at end of list
00650      * to the place of the deletion.
00651      *
00652      * Case 4: Deletion in the middle so that the list does indeed
00653      * wrap in the array. Move as many remaining items at the end
00654      * of the list as will fit to the end of the array, then move
00655      * the rest to the beginning of the array.
00656      */
00657     if (pos == 0) {
00658         list->start = (list->start + count) % list->tab_size;
00659         list->len -= count;
00660     } else if (pos + count == list->len) {
00661         list->len -= count;
00662     } else if (list->start + list->len < list->tab_size) {
00663         memmove(list->tab + list->start + pos,
00664                 list->tab + list->start + pos + count,
00665                 (list->len - pos - count) * sizeof(void *));
00666         list->len -= count;
00667     } else {
00668         /*
00669          * This is not specially efficient, but it's simple and
00670          * works. Faster methods would have to take more special
00671          * cases into account. 
00672          */
00673         for (i = 0; i < list->len - count - pos; ++i) {
00674             from = INDEX(list, pos + i + count);
00675             to = INDEX(list, pos + i);
00676             list->tab[to] = list->tab[from];
00677         }
00678         list->len -= count;
00679     }
00680 }

void gwlist_add_producer List list  ) 
 

Definition at line 378 of file list.c.

References lock, List::num_producers, and unlock.

Referenced by add_service(), alog(), bb_isolate(), bb_smscconn_ready(), bb_suspend(), boxc_sender(), cimd2_stop_cb(), client_init(), dbpool_create(), eq_add_producer(), gw_rwlock_rdlock(), gwtimer_create(), http_caller_create(), main(), main_for_producer_and_consumer(), oisd_stop_cb(), port_add(), run_smsbox(), run_wapbox(), semaphore_create(), server_init(), service_router(), smasi_create(), smpp_create(), sms_router(), sms_to_smsboxes(), smsbox_start(), smsboxc_run(), smsc2_start(), smsc_cimd2_create(), smsc_oisd_create(), smsc_wrapper_create(), store_file_init(), store_spool_init(), submit_action(), udp_receiver(), udp_sender(), udp_start(), wap_appl_init(), wap_push_ota_init(), wap_push_ppg_init(), wapbox_start(), wapboxc_run(), wdp_router(), wdp_to_wapboxes(), wrapper_stop(), wsp_push_client_init(), wsp_session_init(), wsp_unit_init(), wtp_initiator_init(), and wtp_resp_init().

00379 {
00380     lock(list);
00381     ++list->num_producers;
00382     unlock(list);
00383 }

void gwlist_append List list,
void *  item
 

Definition at line 176 of file list.c.

References INDEX, List::len, lock, make_bigger(), List::nonempty, List::tab, and unlock.

Referenced by add_cookie_to_cache(), add_group(), add_push_application_id(), add_sar_transaction(), add_service(), add_tid(), at2_wait_modem_command(), attr_dict_construct(), boxc_receiver(), cfg_add_hooks(), cfg_get_multi_group(), cfg_init(), check_data_content_type_header(), check_do_elements(), cimd2_handle_request(), client_done(), client_thread(), conn_pool_put(), dict_keys(), dict_put(), dict_put_true(), dispatch_into_queue(), dlr_mem_add(), expand_file(), get_matching_translations(), get_x_kannel_from_xml(), gwlist_extract_matching(), gwlist_produce(), gwlist_search_all(), gwthread_join(), gwthread_join_every(), handle_submit(), heartbeat_start(), http_append_headers(), http_header_add(), http_header_add_element(), http_header_duplicate(), http_header_find_all(), http_thread(), http_use_proxy(), init_machine_create(), initialize_clients(), main(), main_for_extract(), main_for_list_add_and_delete(), method_machine_create(), mime_entity_add_part(), mime_entity_duplicate(), mime_something_to_entity(), octstr_split(), octstr_split_words(), oisd_handle_request(), oneuser_add(), parse_cgivars(), parse_data_element(), parse_param_element(), push_client_machine_create(), push_machine_create(), read_mime_headers(), read_some_headers(), refuse_unreplied_capabilities(), reply_known_capabilities(), resp_machine_create(), run_smsbox(), run_wapbox(), session_machine_create(), set_cookies(), sms_split(), smsbox_req_handle(), smsc2_start(), soap_add_msg_cb(), soap_client_init_query(), soap_create_map(), split_headers(), store_push_data(), string_table_add(), string_table_add_many(), string_table_collect_strings(), string_table_collect_words(), string_table_sort_list(), submit_action(), submit_action_nosync(), update_push_data_with_attribute(), update_session_data(), update_session_data_with_headers(), urltrans_add_one(), wap_map_add_url(), wml_charsets(), wml_init(), wsp_cap_duplicate_list(), wsp_cap_unpack_list(), wsp_strip_parameters(), wtp_pdu_append_tpi(), and wtp_unpack_wdp_datagram().

00177 {
00178     lock(list);
00179     make_bigger(list, 1);
00180     list->tab[INDEX(list, list->len)] = item;
00181     ++list->len;
00182     pthread_cond_signal(&list->nonempty);
00183     unlock(list);
00184 }

Here is the call graph for this function:

void gwlist_append_unique List list,
void *  item,
int(*)(void *, void *)  cmp
 

Definition at line 187 of file list.c.

References GET, INDEX, List::len, lock, make_bigger(), List::nonempty, List::tab, and unlock.

00188 {
00189     void *it;
00190     long i;
00191 
00192     lock(list);
00193     it = NULL;
00194     for (i = 0; i < list->len; ++i) {
00195         it = GET(list, i);
00196         if (cmp(it, item)) {
00197             break;
00198         }
00199     }
00200     if (i == list->len) {
00201         /* not yet in list, so add it */
00202         make_bigger(list, 1);
00203         list->tab[INDEX(list, list->len)] = item;
00204         ++list->len;
00205         pthread_cond_signal(&list->nonempty);
00206     }
00207     unlock(list);
00208 }

Here is the call graph for this function:

void* gwlist_consume List list  ) 
 

Definition at line 412 of file list.c.

References delete_items_from_list(), GET, gwthread_self(), List::len, lock, Mutex::mutex, List::nonempty, List::num_producers, Mutex::owner, List::single_operation_lock, and unlock.

Referenced by alog_close(), alog_reopen(), boxc_receiver(), boxc_sender(), cimd2_receive_msg(), consumer(), dbpool_conn_consume(), eq_extract(), gw_rwlock_wrlock(), http_queue_thread(), http_receive_result_real(), http_remove_hop_headers(), io_thread(), main(), main_thread(), obey_request_thread(), oisd_receive_msg(), ota_read_thread(), pack_cache_control(), pap_request_thread(), parse_methodresponse_element(), port_get_request(), run_batch(), semaphore_down(), server_thread(), service_router(), sms_to_smsboxes(), store_file_save(), store_spool_save(), submit_action(), udp_die(), udp_receiver(), udp_sender(), wait_for_connections(), wapboxc_run(), wdp_router(), wdp_to_wapboxes(), wrapper_receiver(), wrapper_sender(), write_request_thread(), wsp_pack_list(), wtp_pdu_destroy(), and xmlrpc_print_struct().

00413 {
00414     void *item;
00415 
00416     lock(list);
00417     while (list->len == 0 && list->num_producers > 0) {
00418         list->single_operation_lock->owner = -1;
00419         pthread_cond_wait(&list->nonempty,
00420                           &list->single_operation_lock->mutex);
00421         list->single_operation_lock->owner = gwthread_self();
00422     }
00423     if (list->len > 0) {
00424         item = GET(list, 0);
00425         delete_items_from_list(list, 0, 1);
00426     } else {
00427         item = NULL;
00428     }
00429     unlock(list);
00430     return item;
00431 }

Here is the call graph for this function:

List* gwlist_create_real void   ) 
 

Definition at line 126 of file list.c.

References List::len, mutex_create, List::nonempty, List::num_producers, List::permanent_lock, List::single_operation_lock, List::start, List::tab, and List::tab_size.

00127 {
00128     List *list;
00129 
00130     list = gw_malloc(sizeof(List));
00131     list->tab = NULL;
00132     list->tab_size = 0;
00133     list->start = 0;
00134     list->len = 0;
00135     list->single_operation_lock = mutex_create();
00136     list->permanent_lock = mutex_create();
00137     pthread_cond_init(&list->nonempty, NULL);
00138     list->num_producers = 0;
00139     return list;
00140 }

void gwlist_delete List list,
long  pos,
long  count
 

Definition at line 229 of file list.c.

References delete_items_from_list(), lock, and unlock.

Referenced by dbpool_check(), dlr_mem_flush(), dlr_mem_remove(), expire_cookies(), have_cookie(), http_header_pack(), http_header_remove_all(), http_header_split_auth_value(), main_for_producer_and_consumer(), mime_entity_remove_part(), mime_entity_replace_part(), pack_challenge(), sanitize_capabilities(), smsc2_restart_smsc(), soap_client_init_query(), and strip_default_capabilities().

00230 {
00231     lock(list);
00232     delete_items_from_list(list, pos, count);
00233     unlock(list);
00234 }

Here is the call graph for this function:

long gwlist_delete_equal List list,
void *  item
 

Definition at line 263 of file list.c.

References delete_items_from_list(), GET, List::len, lock, and unlock.

Referenced by abort_elapsed(), check_pool_conn(), client_destroy(), handle_method_event(), handle_push_event(), init_machine_destroy(), machine_destroy(), main_for_list_add_and_delete(), push_client_machine_destroy(), remove_push_data(), remove_pushless_session(), remove_session_data(), resp_machine_destroy(), route_msg(), run_smsbox(), run_wapbox(), update_push_data_with_attribute(), and update_session_data().

00264 {
00265     long i;
00266     long count;
00267 
00268     lock(list);
00269 
00270     /* XXX this could be made more efficient by noticing
00271        consecutive items to be removed, but leave that for later.
00272        --liw */
00273     i = 0;
00274     count = 0;
00275     while (i < list->len) {
00276         if (GET(list, i) == item) {
00277             delete_items_from_list(list, i, 1);
00278             count++;
00279         } else {
00280             ++i;
00281         }
00282     }
00283     unlock(list);
00284 
00285     return count;
00286 }

Here is the call graph for this function:

long gwlist_delete_matching List list,
void *  pat,
gwlist_item_matches_t matches
 

Definition at line 237 of file list.c.

References delete_items_from_list(), GET, List::len, lock, and unlock.

Referenced by main_for_list_add_and_delete(), smsbox_req_handle(), update_push_data_with_attribute(), and update_session_data_with_headers().

00238 {
00239     long i;
00240     long count;
00241 
00242     lock(list);
00243 
00244     /* XXX this could be made more efficient by noticing
00245        consecutive items to be removed, but leave that for later.
00246        --liw */
00247     i = 0;
00248     count = 0;
00249     while (i < list->len) {
00250         if (matches(GET(list, i), pat)) {
00251             delete_items_from_list(list, i, 1);
00252             count++;
00253         } else {
00254             ++i;
00255         }
00256     }
00257     unlock(list);
00258 
00259     return count;
00260 }

Here is the call graph for this function:

void gwlist_destroy List list,
gwlist_item_destructor_t destructor
 

Definition at line 143 of file list.c.

References gwlist_extract_first(), mutex_destroy(), List::nonempty, List::permanent_lock, List::single_operation_lock, and List::tab.

Referenced by action_destroy(), add_group(), alog_close(), at2_detect_modem_type(), at2_device_thread(), at2_init_device(), at2_read_modems(), attribute_destroy(), brunet_parse_body(), cfg_dump(), cfg_read(), cfg_shutdown(), cgw_sender(), check_do_elements(), cimd2_destroy(), clear_old_concat_parts(), clickatell_parse_body(), client_shutdown(), client_thread(), config_reload(), conn_pool_item_destroy(), cookies_destroy(), create_onetrans(), dbpool_destroy(), delete_threadinfo(), destroy_clients(), destroy_group_list(), destroy_keyword_list(), destroy_methodmachines(), destroy_onetrans(), destroy_pushmachines(), destroy_users_list(), dict_destroy(), dict_remove(), disconnect_other_sessions(), dispatch_datagram(), dlr_init_mysql(), dlr_init_pgsql(), dlr_mem_shutdown(), dlr_pgsql_get(), dlr_pgsql_messages(), do_dump(), do_queue_cleanup(), empty_msg_lists(), eq_destroy(), expand_file(), fake_listener(), fdset_destroy(), find_translation(), get_pattern(), grp_dump(), gw_rwlock_destroy(), gwlist_extract_matching(), gwlist_search_all(), handle_submit(), heartbeat_stop(), http_caller_destroy(), http_close_proxy(), http_destroy_cgiargs(), http_destroy_headers(), http_remove_hop_headers(), init_bearerbox(), init_reroute(), init_smsbox(), init_smsbox_routes(), io_thread(), main(), main_for_extract(), main_for_list_add_and_delete(), mime_entity_destroy(), numhash_create(), oisd_destroy(), pack_accept(), pack_accept_charset(), pack_accept_encoding(), pack_accept_language(), pack_cache_control(), pack_challenge(), pack_content_disposition(), pack_credentials(), pack_known_header(), parse_context_destroy(), parse_methodresponse_element(), parse_request_line(), pattern_list_matches_ip(), port_remove(), port_shutdown(), prefix_allowed(), push_machines_list_destroy(), randomize(), read_ppg_config(), receive_reply(), release_holding_methods(), run_smsbox(), run_wapbox(), semaphore_destroy(), send_message(), server_shutdown(), smasi_destroy(), smpp_destroy(), smsbox_req_handle(), smsbox_req_sendota(), smsboxc_run(), smsc2_cleanup(), smsc_cgw_create(), smsc_fake_create(), smsc_soap_create(), smscconn_destroy(), smscconn_send(), smscwrapper_destroy(), soap_create_map(), soap_fetch_xml_data(), soap_listener(), soap_map_xml_data(), soap_parse_dlr(), soap_parse_mo(), soap_parse_response(), soap_release_dependences(), soap_server(), store_file_load(), store_file_shutdown(), store_file_status(), store_spool_shutdown(), string_table_add_many(), string_table_build(), string_table_collect_words(), string_table_sort_list(), udp_die(), udp_start(), udpc_destroy(), urltrans_add_cfg(), urltrans_destroy(), urltrans_fill_escape_codes(), wap_appl_shutdown(), wap_dispatch_datagram(), wap_map_destroy(), wap_push_ota_shutdown(), wap_push_ppg_pushuser_list_add(), wap_push_ppg_pushuser_list_destroy(), wap_push_ppg_pushuser_search_ip_from_wildcarded_list(), wap_push_ppg_shutdown(), wapboxc_run(), wdp_to_wapboxes(), wildcarded_ip_found(), wml_binary_destroy(), wml_shutdown(), wrapper_sender(), wsp_cap_destroy_list(), wsp_push_client_shutdown(), wsp_session_shutdown(), wsp_unit_shutdown(), wtp_event_dump(), wtp_initiator_shutdown(), wtp_pdu_destroy(), wtp_resp_shutdown(), wtp_tid_cache_shutdown(), xmlrpc_call_destroy(), xmlrpc_print_struct(), and xmlrpc_value_destroy().

00144 {
00145     void *item;
00146 
00147     if (list == NULL)
00148         return;
00149 
00150     if (destructor != NULL) {
00151         while ((item = gwlist_extract_first(list)) != NULL)
00152             destructor(item);
00153     }
00154 
00155     mutex_destroy(list->permanent_lock);
00156     mutex_destroy(list->single_operation_lock);
00157     pthread_cond_destroy(&list->nonempty);
00158     gw_free(list->tab);
00159     gw_free(list);
00160 }

Here is the call graph for this function:

void* gwlist_extract_first List list  ) 
 

Definition at line 302 of file list.c.

References delete_items_from_list(), GET, gw_assert, List::len, lock, and unlock.

Referenced by add_group(), alert_joiners(), at2_read_modems(), at2_read_pending_incoming_messages(), brunet_parse_body(), cfg_dump(), cfg_read(), cgw_open_send_connection(), cgw_send_loop(), cgw_sender(), cgw_shutdown_cb(), cimd2_shutdown_cb(), clear_old_concat_parts(), clickatell_parse_body(), config_reload(), conn_pool_get(), dbpool_decrease(), dict_destroy(), dispatch_datagram(), dlr_init_mysql(), dlr_init_pgsql(), dlr_pgsql_get(), dlr_pgsql_messages(), do_queue_cleanup(), empty_msg_lists(), expand_file(), fake_listener(), grp_dump(), gwlist_destroy(), heartbeat_stop(), http_cgivar_dump_into(), http_destroy_cgiargs(), http_receive_result_real(), init_reroute(), init_smsbox_routes(), io_thread(), main(), main_connection_loop(), oisd_shutdown_cb(), parse_context_destroy(), parse_pop_limit(), pattern_list_matches_ip(), poller(), port_remove(), receive_push_reply(), receive_reply(), reconnect(), run_requests(), run_smsbox(), send_message(), send_messages(), server_thread(), shutdown_cb(), smsbox_req_handle(), smsbox_req_sendota(), smsc_soap_create(), soap_client_init_query(), soap_create_map(), soap_listener(), soap_release_dependences(), soap_send_loop(), soap_shutdown_cb(), store_file_load(), string_table_add_many(), string_table_build(), string_table_collect_words(), string_table_output(), string_table_sort_list(), udp_start(), urltrans_add_cfg(), wap_dispatch_datagram(), wap_push_ppg_pushuser_list_add(), wdp_to_wapboxes(), wrapper_sender(), wrapper_shutdown(), and wtp_event_dump().

00303 {
00304     void *item;
00305 
00306     gw_assert(list != NULL);
00307     lock(list);
00308     if (list->len == 0)
00309         item = NULL;
00310     else {
00311         item = GET(list, 0);
00312         delete_items_from_list(list, 0, 1);
00313     }
00314     unlock(list);
00315     return item;
00316 }

Here is the call graph for this function:

List* gwlist_extract_matching List list,
void *  pat,
gwlist_item_matches_t cmp
 

Definition at line 319 of file list.c.

References delete_items_from_list(), GET, gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_len(), List::len, lock, and unlock.

Referenced by dict_remove(), heartbeat_stop(), and main_for_extract().

00320 {
00321     List *new_list;
00322     long i;
00323 
00324     new_list = gwlist_create();
00325     lock(list);
00326     i = 0;
00327     while (i < list->len) {
00328         if (cmp(GET(list, i), pat)) {
00329             gwlist_append(new_list, GET(list, i));
00330             delete_items_from_list(list, i, 1);
00331         } else
00332             ++i;
00333     }
00334     unlock(list);
00335 
00336     if (gwlist_len(new_list) == 0) {
00337         gwlist_destroy(new_list, NULL);
00338         return NULL;
00339     }
00340     return new_list;
00341 }

Here is the call graph for this function:

void* gwlist_get List list,
long  pos
 

Definition at line 289 of file list.c.

References GET, gw_assert, lock, and unlock.

Referenced by abort_delivery(), abort_methods(), abort_pushes(), boxc_incoming_wdp_queue(), boxc_status(), build_request(), build_response(), cfg_get_multi_group(), check_do_elements(), client_thread(), create_onetrans(), dbpool_check(), deliver_pending_pushes(), dict_keys(), dict_remove(), disconnect_other_sessions(), dlr_mem_get(), dlr_mem_remove(), dlr_pgsql_get(), dlr_pgsql_messages(), do_dump(), dump_tpis(), expire_cookies(), find_default_translation(), find_translation(), get_cookies(), get_matching_translations(), get_pattern(), get_qvalue(), handle_submit(), have_cookie(), http_append_headers(), http_cgi_variable(), http_cgivar_dump(), http_header_dump(), http_header_duplicate(), http_header_find_all(), http_header_find_first_real(), http_header_get(), http_header_pack(), http_header_remove_all(), http_header_split_auth_value(), http_header_value(), http_send_reply(), http_something_accepted(), http_use_proxy(), init_reroute(), init_smsbox_routes(), is_allowed_in_group(), is_single_group(), main(), main_for_extract(), main_for_list_add_and_delete(), main_for_producer_and_consumer(), mime_decompile(), mime_entity_dump_real(), mime_entity_duplicate(), mime_entity_get_part(), mime_entity_remove_part(), mime_entity_replace_part(), mime_entity_to_octstr(), mime_multipart_start_elem(), pack_challenge(), pack_tpis(), parse_attr_value(), parse_request_line(), prefix_allowed(), proxy_used_for_host(), randomize(), read_mime_headers(), read_some_headers(), refuse_unreplied_capabilities(), release_holding_methods(), remove_session_data(), route_incoming_to_boxc(), route_msg(), sanitize_capabilities(), set_cookies(), sms_split(), sms_to_smsboxes(), smsbox_req_handle(), smsc2_cleanup(), smsc2_find(), smsc2_restart_smsc(), smsc2_resume(), smsc2_rout(), smsc2_shutdown(), smsc2_start(), smsc2_status(), smsc2_stop_smsc(), smsc2_suspend(), smscconn_send(), soap_client_have_response(), soap_client_init_query(), soap_create_map(), soap_fetch_xml_data(), soap_get_index(), soap_map_xml_data(), soap_release_dependences(), store_file_status(), string_table_add(), string_table_apply(), string_table_sort_list(), strip_default_capabilities(), test_header_combine(), udp_addwdp(), udp_outgoing_queue(), udpc_find_mapping(), unpack_ack(), urltrans_fill_escape_codes(), urltrans_find_service(), urltrans_find_username(), user_find_by_username(), wap_map_destroy(), wap_map_url(), wap_push_ppg_pushuser_search_ip_from_wildcarded_list(), wdp_to_wapboxes(), wildcarded_ip_found(), wrapper_sender(), wsp_cap_dump_list(), wsp_cap_duplicate_list(), wsp_cap_get_data(), wsp_cap_pack_list(), wsp_headers_unpack(), wsp_pack_parameters(), xmlrpc_call_print(), xmlrpc_get_element(), xmlrpc_get_param(), and xmlrpc_print_array().

00290 {
00291     void *item;
00292 
00293     lock(list);
00294     gw_assert(pos >= 0);
00295     gw_assert(pos < list->len);
00296     item = GET(list, pos);
00297     unlock(list);
00298     return item;
00299 }

void gwlist_insert List list,
long  pos,
void *  item
 

Definition at line 211 of file list.c.

References GET, gw_assert, INDEX, List::len, lock, make_bigger(), List::nonempty, List::tab, and unlock.

Referenced by cfg_read(), expand_file(), handle_transaction(), http_header_pack(), machine_create(), mime_entity_replace_part(), parse_limit(), sms_to_smsboxes(), and smsc2_restart_smsc().

00212 {
00213     long i;
00214 
00215     lock(list);
00216     gw_assert(pos >= 0);
00217     gw_assert(pos <= list->len);
00218 
00219     make_bigger(list, 1);
00220     for (i = list->len; i > pos; --i)
00221         list->tab[INDEX(list, i)] = GET(list, i - 1);
00222     list->tab[INDEX(list, pos)] = item;
00223     ++list->len;
00224     pthread_cond_signal(&list->nonempty);
00225     unlock(list);
00226 }

Here is the call graph for this function:

long gwlist_len List list  ) 
 

Definition at line 163 of file list.c.

References List::len, lock, and unlock.

Referenced by abort_delivery(), abort_methods(), abort_pushes(), at2_device_thread(), at2_read_modems(), at2_read_pending_incoming_messages(), at2_read_sms_memory(), bb_print_status(), boxc_incoming_wdp_queue(), boxc_status(), brunet_parse_body(), build_request(), build_response(), cfg_get_multi_group(), cgw_queued_cb(), cgw_sender(), check_application_headers(), check_do_elements(), check_num_args(), cimd2_destroy(), cimd2_queued_cb(), cimd2_receive_msg(), clickatell_parse_body(), client_thread(), content_transformable(), create_onetrans(), dbpool_check(), dbpool_conn_count(), decode_bearer_indication(), deliver_pending_pushes(), destroy_methodmachines(), destroy_pushmachines(), dict_keys(), dict_remove(), disconnect_other_sessions(), dispatch_datagram(), dlr_mem_flush(), dlr_mem_get(), dlr_mem_messages(), dlr_mem_remove(), dlr_pgsql_get(), dlr_pgsql_messages(), do_dump(), dump_tpis(), empty_msg_lists(), expire_cookies(), fdset_destroy(), find_default_translation(), find_translation(), get_cookies(), get_matching_translations(), get_pattern(), get_qvalue(), get_x_kannel_from_headers(), gwlist_extract_matching(), gwlist_search_all(), handle_submit(), have_cookie(), heartbeat_stop(), http_append_headers(), http_cgi_variable(), http_cgivar_dump(), http_header_combine(), http_header_dump(), http_header_duplicate(), http_header_find_all(), http_header_find_first_real(), http_header_pack(), http_header_remove_all(), http_header_split_auth_value(), http_header_value(), http_queue_thread(), http_send_reply(), http_something_accepted(), http_use_proxy(), indicate_push_connection(), indicate_push_resume(), init_batch(), init_reroute(), init_smsbox_routes(), is_allowed_in_group(), is_single_group(), main(), main_for_extract(), main_for_list_add_and_delete(), main_for_producer_and_consumer(), mime_decompile(), mime_entity_dump_real(), mime_entity_duplicate(), mime_entity_num_parts(), mime_entity_to_octstr(), mime_multipart_start_elem(), oisd_destroy(), oisd_queued_cb(), oisd_receive_msg(), pack_appid_list(), pack_challenge(), pack_tpis(), parse_attr_value(), parse_context_destroy(), parse_methodresponse_element(), parse_pop_limit(), parse_request_line(), prefix_allowed(), proxy_used_for_host(), queued_cb(), randomize(), read_mime_headers(), read_some_headers(), refuse_unreplied_capabilities(), release_holding_methods(), remove_pushless_session(), remove_session_data(), route_incoming_to_boxc(), route_msg(), run_smsbox(), run_wapbox(), sanitize_capabilities(), semaphore_getvalue(), send_message(), set_cookies(), sms_router(), sms_to_smsboxes(), smsbox_req_handle(), smsbox_sendota_post(), smsc2_cleanup(), smsc2_find(), smsc2_restart_smsc(), smsc2_resume(), smsc2_rout(), smsc2_shutdown(), smsc2_start(), smsc2_status(), smsc2_suspend(), smsc_soap_create(), smscconn_send(), soap_add_msg_cb(), soap_client_have_response(), soap_client_init_query(), soap_create_map(), soap_fetch_xml_data(), soap_get_index(), soap_listener(), soap_map_xml_data(), soap_parse_mo(), soap_queued_cb(), soap_read_response(), soap_release_dependences(), store_file_status(), string_table_add(), string_table_add_many(), string_table_apply(), string_table_build(), string_table_collect_words(), string_table_sort_list(), strip_default_capabilities(), test_header_combine(), udp_addwdp(), udp_outgoing_queue(), udp_start(), udpc_destroy(), udpc_find_mapping(), unpack_ack(), urltrans_fill_escape_codes(), urltrans_find_username(), user_find_by_username(), wap_appl_get_load(), wap_dispatch_datagram(), wap_map_destroy(), wap_map_url(), wap_push_ppg_pushuser_search_ip_from_wildcarded_list(), wap_push_ppg_shutdown(), wdp_to_wapboxes(), wildcarded_ip_found(), wrapper_queued(), wrapper_sender(), write_request_thread(), wsp_cap_dump_list(), wsp_cap_duplicate_list(), wsp_cap_get_data(), wsp_cap_pack_list(), wsp_headers_pack(), wsp_headers_unpack(), wsp_pack_parameters(), wsp_push_client_shutdown(), wsp_session_shutdown(), wtp_event_dump(), wtp_initiator_shutdown(), wtp_pdu_destroy(), wtp_resp_shutdown(), wtp_tid_cache_shutdown(), xmlrpc_call_print(), xmlrpc_count_elements(), xmlrpc_count_params(), xmlrpc_get_param(), and xmlrpc_print_array().

00164 {
00165     long len;
00166 
00167     if (list == NULL)
00168         return 0;
00169     lock(list);
00170     len = list->len;
00171     unlock(list);
00172     return len;
00173 }

void gwlist_lock List list  ) 
 

Definition at line 344 of file list.c.

References gw_assert, mutex_lock, and List::permanent_lock.

Referenced by alog(), alog_close(), alog_reopen(), boxc_incoming_wdp_queue(), boxc_status(), client_destroy(), dbpool_check(), dbpool_conn_consume(), dbpool_decrease(), dbpool_increase(), gw_rwlock_rdlock(), gw_rwlock_wrlock(), port_remove(), route_msg(), run_wapbox(), set_tid_by_item(), soap_client_have_response(), soap_client_init_query(), udp_addwdp(), udp_outgoing_queue(), udpc_find_mapping(), wdp_to_wapboxes(), and xmlrpc_call_print().

00345 {
00346     gw_assert(list != NULL);
00347     mutex_lock(list->permanent_lock);
00348 }

void gwlist_produce List list,
void *  item
 

Definition at line 406 of file list.c.

References gwlist_append().

Referenced by add_msg_cb(), bb_smscconn_send_failed(), boxc_receiver(), boxc_sender(), cgw_add_msg_cb(), cgw_check_acks(), cgw_send_loop(), cimd2_add_msg_cb(), client_create(), dbpool_conn_produce(), dbpool_increase(), elapse_timer(), eq_append(), handle_action(), handle_transaction(), http_close_port(), http_open_port_if(), http_read_thread(), http_start_request(), https_read_thread(), oisd_add_msg_cb(), port_put_request(), producer(), read_messages_from_bearerbox(), route_incoming_to_boxc(), route_msg(), run_smsbox(), semaphore_create(), semaphore_up(), send_msg_cb(), sms_router(), sms_to_smsboxes(), smsc2_rout(), udp_addwdp(), udp_addwdp_from_client(), udp_addwdp_from_server(), udp_receiver(), url_result_thread(), wap_appl_dispatch(), wap_push_ota_dispatch_event(), wap_push_ppg_dispatch_event(), wdp_to_wapboxes(), wrapper_add_msg(), write_request_thread(), wsp_push_client_dispatch_event(), wsp_session_dispatch_event(), wsp_unit_dispatch_event(), wtp_initiator_dispatch_event(), wtp_resp_dispatch_event(), xmlrpc_add_element(), and xmlrpc_call_add_param().

00407 {
00408     gwlist_append(list, item);
00409 }

Here is the call graph for this function:

int gwlist_producer_count List list  ) 
 

Definition at line 386 of file list.c.

References lock, List::num_producers, and unlock.

Referenced by gw_rwlock_wrlock(), main(), run_smsbox(), run_wapbox(), and sms_to_smsboxes().

00387 {
00388     int ret;
00389     lock(list);
00390     ret = list->num_producers;
00391     unlock(list);
00392     return ret;
00393 }

void gwlist_remove_producer List list  ) 
 

Definition at line 396 of file list.c.

References gw_assert, lock, List::nonempty, List::num_producers, and unlock.

Referenced by alog(), bb_isolate(), bb_resume(), bb_smscconn_killed(), boxc_sender(), cimd2_shutdown_cb(), cimd2_start_cb(), client_shutdown(), dbpool_destroy(), eq_remove_producer(), gw_rwlock_unlock(), gwtimer_destroy(), http_caller_signal_shutdown(), main(), oisd_shutdown_cb(), oisd_start_cb(), port_remove(), producer(), run_smsbox(), run_wapbox(), server_shutdown(), service_router(), set_shutdown_status(), sms_router(), sms_to_smsboxes(), smsboxc_run(), smsc2_shutdown(), smsc2_start(), store_file_load(), store_spool_load(), udp_die(), udp_receiver(), udp_sender(), udp_shutdown(), wap_appl_shutdown(), wap_push_ota_shutdown(), wap_push_ppg_shutdown(), wapboxc_run(), wdp_router(), wdp_to_wapboxes(), wrapper_sender(), wrapper_shutdown(), wrapper_start(), wsp_push_client_shutdown(), wsp_session_shutdown(), wsp_unit_shutdown(), wtp_initiator_shutdown(), and wtp_resp_shutdown().

00397 {
00398     lock(list);
00399     gw_assert(list->num_producers > 0);
00400     --list->num_producers;
00401     pthread_cond_broadcast(&list->nonempty);
00402     unlock(list);
00403 }

void* gwlist_search List list,
void *  pattern,
int(*)(void *, void *)  cmp
 

Definition at line 463 of file list.c.

References GET, List::len, lock, and unlock.

00464 {
00465     void *item;
00466     long i;
00467 
00468     lock(list);
00469     item = NULL;
00470     for (i = 0; i < list->len; ++i) {
00471         item = GET(list, i);
00472         if (cmp(item, pattern)) {
00473             break;
00474         }
00475     }
00476     if (i == list->len) {
00477         item = NULL;
00478     }
00479     unlock(list);
00480 
00481     return item;
00482 }

List* gwlist_search_all List list,
void *  pattern,
int(*)(void *, void *)  cmp
 

Definition at line 486 of file list.c.

References GET, gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_len(), List::len, lock, and unlock.

00487 {
00488     List *new_list;
00489     void *item;
00490     long i;
00491 
00492     new_list = gwlist_create();
00493 
00494     lock(list);
00495     item = NULL;
00496     for (i = 0; i < list->len; ++i) {
00497         item = GET(list, i);
00498         if (cmp(item, pattern))
00499             gwlist_append(new_list, item);
00500     }
00501     unlock(list);
00502 
00503     if (gwlist_len(new_list) == 0) {
00504         gwlist_destroy(new_list, NULL);
00505         new_list = NULL;
00506     }
00507 
00508     return new_list;
00509 }

Here is the call graph for this function:

void gwlist_sort List list,
int(*)(const void *, const void *)  cmp
 

Definition at line 512 of file list.c.

References GET, gw_assert, List::len, lock, and unlock.

Referenced by main().

00513 {
00514     gw_assert(list != NULL && cmp != NULL);
00515 
00516     lock(list);
00517     if (list->len == 0) {
00518         /* nothing to sort */
00519         unlock(list);
00520         return;
00521     }
00522     qsort(&GET(list, 0), list->len, sizeof(void*), cmp);
00523     unlock(list);
00524 }

void* gwlist_timed_consume List list,
long  sec
 

Definition at line 434 of file list.c.

References delete_items_from_list(), GET, gwthread_self(), List::len, lock, Mutex::mutex, List::nonempty, List::num_producers, Mutex::owner, List::single_operation_lock, and unlock.

Referenced by sms_router().

00435 {
00436     void *item;
00437     struct timespec abstime;
00438     int rc;
00439 
00440     abstime.tv_sec = time(NULL) + sec;
00441     abstime.tv_nsec = 0;
00442 
00443     lock(list);
00444     while (list->len == 0 && list->num_producers > 0) {
00445         list->single_operation_lock->owner = -1;
00446         rc = pthread_cond_timedwait(&list->nonempty,
00447                           &list->single_operation_lock->mutex, &abstime);
00448         list->single_operation_lock->owner = gwthread_self();
00449         if (rc == ETIMEDOUT)
00450             break;
00451     }
00452     if (list->len > 0) {
00453         item = GET(list, 0);
00454         delete_items_from_list(list, 0, 1);
00455     } else {
00456         item = NULL;
00457     }
00458     unlock(list);
00459     return item;
00460 }

Here is the call graph for this function:

void gwlist_unlock List list  ) 
 

Definition at line 351 of file list.c.

References gw_assert, mutex_unlock, and List::permanent_lock.

Referenced by alog(), alog_close(), alog_reopen(), boxc_incoming_wdp_queue(), boxc_status(), client_destroy(), dbpool_check(), dbpool_conn_consume(), dbpool_decrease(), dbpool_increase(), gw_rwlock_rdlock(), gw_rwlock_unlock(), port_remove(), route_msg(), run_wapbox(), set_tid_by_item(), soap_client_have_response(), soap_client_init_query(), udp_addwdp(), udp_outgoing_queue(), udpc_find_mapping(), wdp_to_wapboxes(), and xmlrpc_call_print().

00352 {
00353     gw_assert(list != NULL);
00354     mutex_unlock(list->permanent_lock);
00355 }

int gwlist_wait_until_nonempty List list  ) 
 

Definition at line 358 of file list.c.

References gwthread_self(), List::len, lock, Mutex::mutex, List::nonempty, List::num_producers, Mutex::owner, List::single_operation_lock, and unlock.

Referenced by smsboxc_run(), wait_for_connections(), and wapboxc_run().

00359 {
00360     int ret;
00361 
00362     lock(list);
00363     while (list->len == 0 && list->num_producers > 0) {
00364         list->single_operation_lock->owner = -1;
00365         pthread_cond_wait(&list->nonempty,
00366                           &list->single_operation_lock->mutex);
00367         list->single_operation_lock->owner = gwthread_self();
00368     }
00369     if (list->len > 0)
00370         ret = 1;
00371     else
00372         ret = -1;
00373     unlock(list);
00374     return ret;
00375 }

Here is the call graph for this function:

long gwthread_self void   ) 
 

Definition at line 626 of file gwthread-pthread.c.

References threadinfo::number, and tsd_key.

Referenced by client_thread(), conn_claim(), fdset_destroy(), fdset_listen(), fdset_register(), fdset_set_timeout(), fdset_unregister(), find_entry(), gw_prioqueue_consume(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_consume(), gwlist_timed_consume(), gwlist_wait_until_nonempty(), gwthread_create_real(), gwthread_join_all(), gwthread_wakeup_all(), handle_action(), lock_in(), lock_out(), mutex_lock_real(), mutex_trylock_real(), new_thread(), openssl_init_locks(), producer(), and push_thread().

00627 {
00628     struct threadinfo *threadinfo;
00629     threadinfo = pthread_getspecific(tsd_key);
00630     if (threadinfo) 
00631         return threadinfo->number;
00632     else
00633         return -1;
00634 }

void lock List list  )  [static]
 

Definition at line 529 of file list.c.

References gw_assert, mutex_lock, and List::single_operation_lock.

00530 {
00531     gw_assert(list != NULL);
00532     mutex_lock(list->single_operation_lock);
00533 }

void make_bigger List list,
long  items
[static]
 

Definition at line 548 of file list.c.

References gw_assert, List::len, List::start, List::tab, and List::tab_size.

Referenced by gw_prioqueue_create(), gw_prioqueue_insert(), gwlist_append(), gwlist_append_unique(), and gwlist_insert().

00549 {
00550     long old_size, new_size;
00551     long len_at_beginning, len_at_end;
00552 
00553     if (list->len + items <= list->tab_size)
00554         return;
00555 
00556     old_size = list->tab_size;
00557     new_size = old_size + items;
00558     list->tab = gw_realloc(list->tab, new_size * sizeof(void *));
00559     list->tab_size = new_size;
00560 
00561     /*
00562      * Now, one of the following situations is in effect
00563      * (* is used, empty is unused element):
00564      *
00565      * Case 1: Used area did not wrap. No action is necessary.
00566      * 
00567      *             old_size              new_size
00568      *             v                     v
00569      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00570      * | |*|*|*|*|*|*| | | | | | | | | | | | | | | | |
00571      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00572      *   ^           ^
00573      *   start       start+len
00574      * 
00575      * Case 2: Used area wrapped, but the part at the beginning
00576      * of the array fits into the new area. Action: move part
00577      * from beginning to new area.
00578      * 
00579      *             old_size              new_size
00580      *             v                     v
00581      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00582      * |*|*| | | | | | | |*|*|*| | | | | | | | | | | |
00583      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00584      *     ^             ^
00585      *     start+len     start
00586      * 
00587      * Case 3: Used area wrapped, and the part at the beginning
00588      * of the array does not fit into the new area. Action: move
00589      * as much as will fit from beginning to new area and move
00590      * the rest to the beginning.
00591      * 
00592      *                    old_size   new_size
00593      *                       v   v
00594      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00595      * |*|*|*|*|*|*|*|*|*| | | | | | | | |*|*|*|*| | |
00596      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
00597      *           ^               ^
00598      *           start+len       start
00599      */
00600 
00601     gw_assert(list->start < old_size ||
00602               (list->start == 0 && old_size == 0));
00603     if (list->start + list->len > old_size) {
00604         len_at_end = old_size - list->start;
00605         len_at_beginning = list->len - len_at_end;
00606         if (len_at_beginning <= new_size - old_size) {
00607             /* This is Case 2. */
00608             memmove(list->tab + old_size,
00609                     list->tab,
00610                     len_at_beginning * sizeof(void *));
00611         } else {
00612             /* This is Case 3. */
00613             memmove(list->tab + old_size,
00614                     list->tab,
00615                     (new_size - old_size) * sizeof(void *));
00616             memmove(list->tab,
00617                     list->tab + (new_size - old_size),
00618                     (len_at_beginning - (new_size - old_size))
00619                     * sizeof(void *));
00620         }
00621     }
00622 }

void unlock List list  )  [static]
 

Definition at line 535 of file list.c.

References gw_assert, mutex_unlock, and List::single_operation_lock.

00536 {
00537     gw_assert(list != NULL);
00538     mutex_unlock(list->single_operation_lock);
00539 }

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.