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

list.h

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  * list.h - generic dynamic list
00059  *
00060  * This is a generic, dynamic list. Generic means that it stores void pointers
00061  * (void *), instead of a more specific data type. This allows storage of
00062  * any type of items in the list. The pointers may not be NULL pointers.
00063  *
00064  * A number of operations are defined for the list: create, destroy,
00065  * query of length, inserting and deleting items, getting items, and so on.
00066  * See below for a detailed list.
00067  *
00068  * The list is also thread safe: each single operation is atomic. For
00069  * list manipulation that needs to be atomic but uses several single
00070  * operations, the list supports locking and unlocking. It is up to the
00071  * caller to make sure the list lock is used properly; the implementation
00072  * only guarantees the atomicity of single operations.
00073  *
00074  * The API also has functions for solving typical producer-consumer problems:
00075  * the list counts the number of producers it has (they need to register
00076  * _and_ unregister explicitly) and has functions for adding a produced
00077  * item to the list and removing an item so that it can be consumed. The
00078  * consumption function (`gwlist_consume') sleeps, without using processor
00079  * time, until there is an item to be consumed or there are no more
00080  * producers. Thus, a typical producer would look like this:
00081  *
00082  *  gwlist_add_producer(list);
00083  *  while ((item = foo()) != NULL)
00084  *      gwlist_produce(list, item);
00085  *  gwlist_remove_producer(list);
00086  *
00087  * and the corresponding consumer would look like this:
00088  *
00089  *  while ((item = gwlist_consume(list)) != NULL)
00090  *      bar(item);
00091  *
00092  * There can be any number of producers and consumers at the same time.
00093  *
00094  * List items are numbered starting with `0'.
00095  *
00096  * Most list functions can do memory allocations. If these allocations
00097  * fail, they will kill the program (they use gwlib/gwmem.c for
00098  * memory allocations, and those do the killing). This is not mentioned
00099  * explicitly for each function.
00100  *
00101  * The module prefix is `list' (in any combination of upper and lower case
00102  * characters). All externally visible symbols (i.e., those defined by
00103  * this header file) start with the prefix.
00104  */
00105 
00106 #ifndef LIST_H
00107 #define LIST_H
00108 
00109 
00110 /*
00111  * The list type. It is opaque: do not touch it except via the functions
00112  * defined in this header.
00113  */
00114 typedef struct List List;
00115 
00116 
00117 /*
00118  * A comparison function for list items. Returns true (non-zero) for
00119  * equal, false for non-equal. Gets an item from the list as the first
00120  * argument, the pattern as a second argument.
00121  */
00122 typedef int gwlist_item_matches_t(void *item, void *pattern);
00123 
00124 
00125 /*
00126  * A destructor function for list items.  Must free all memory associated
00127  * with the list item.
00128  */
00129 typedef void gwlist_item_destructor_t(void *item);
00130 
00131 
00132 /*
00133  * Create a list and return a pointer to the list object.
00134  */
00135 List *gwlist_create_real(void);
00136 #define gwlist_create() gw_claim_area(gwlist_create_real())
00137 
00138 /*
00139  * Destroy the list. If `destructor' is not NULL, first destroy all items
00140  * by calling it for each item. If it is NULL, the caller is responsible
00141  * for destroying items. The caller is also responsible for making sure
00142  * that nothing else tries to touch the list from the time the call to
00143  * gwlist_destroy starts - this includes the item destructor function.
00144  */
00145 void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor);
00146 
00147 
00148 /*
00149  * Return the number of items in the list.  Return 0 if list is NULL.
00150  */
00151 long gwlist_len(List *list);
00152 
00153 
00154 /*
00155  * Add a new item to the end of the list.
00156  */
00157 void gwlist_append(List *list, void *item);
00158 
00159 
00160 /*
00161  * This is similar to gwlist_append(). If the item is *not* present in the 
00162  * list it is added to the end of the list, otherwise the item is 
00163  * discarded and *not* added to the list. Hence you can assume that using
00164  * this append function you result in a unique item inside the list.
00165  */
00166 void gwlist_append_unique(List *list, void *item, gwlist_item_matches_t *cmp);
00167 
00168 
00169 /*
00170  * Insert an item into the list so that it becomes item number `pos'.
00171  */
00172 void gwlist_insert(List *list, long pos, void *item);
00173 
00174 
00175 /*
00176  * Delete items from the list. Note that this does _not_ free the memory
00177  * for the items, they are just dropped from the list.
00178  */
00179 void gwlist_delete(List *list, long pos, long count);
00180 
00181 
00182 /*
00183  * Delete all items from the list that match `pattern'. Like gwlist_delete,
00184  * the items are removed from the list, but are not destroyed themselves.
00185  * Return the number of items deleted.
00186  */
00187 long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *cmp);
00188 
00189 
00190 /*
00191  * Delete all items from the list whose pointer value is exactly `item'.
00192  * Return the number of items deleted.
00193  */
00194 long gwlist_delete_equal(List *list, void *item);
00195 
00196 
00197 /*
00198  * Return the item at position `pos'.
00199  */
00200 void *gwlist_get(List *list, long pos);
00201 
00202 
00203 /*
00204  * Remove and return the first item in the list. Return NULL if list is
00205  * empty. Note that unlike gwlist_consume, this won't sleep until there is
00206  * something in the list.
00207  */
00208 void *gwlist_extract_first(List *list);
00209 
00210 
00211 /*
00212  * Create a new list with items from `list' that match a pattern. The items
00213  * are removed from `list'. Return NULL if no matching items are found.
00214  * Note that unlike gwlist_consume, this won't sleep until there is
00215  * something in the list.
00216  */
00217 List *gwlist_extract_matching(List *list, void *pat, gwlist_item_matches_t *cmp);
00218 
00219 
00220 /*
00221  * Lock the list. This protects the list from other threads that also
00222  * lock the list with gwlist_lock, but not from threads that do not.
00223  * (This is intentional.)
00224  */
00225 void gwlist_lock(List *list);
00226 
00227 
00228 /*
00229  * Unlock the list lock locked by gwlist_lock. Only the owner of the lock
00230  * may unlock it (although this might not be checked).
00231  */
00232 void gwlist_unlock(List *list);
00233 
00234 
00235 /*
00236  * Sleep until the list is non-empty. Note that after the thread awakes
00237  * another thread may already have emptied the list again. Those who wish
00238  * to use this function need to be very careful with gwlist_lock and
00239  * gwlist_unlock.
00240  */
00241 int gwlist_wait_until_nonempty(List *list);
00242 
00243 
00244 /*
00245  * Register a new producer to the list.
00246  */
00247 void gwlist_add_producer(List *list);
00248 
00249 /*
00250  * Return the current number of producers for the list
00251  */
00252 int gwlist_producer_count(List *list);
00253 
00254 /*
00255  * Remove a producer from the list. If the number of producers drops to
00256  * zero, all threads sleeping in gwlist_consume will awake and return NULL.
00257  */
00258 void gwlist_remove_producer(List *list);
00259 
00260 
00261 /*
00262  * Add an item to the list. This equivalent to gwlist_append, but may be
00263  * easier to remember.
00264  */
00265 void gwlist_produce(List *list, void *item);
00266 
00267 
00268 /*
00269  * Remove an item from the list, or return NULL if the list was empty
00270  * and there were no producers. If the list is empty but there are
00271  * producers, sleep until there is something to return.
00272  */
00273 void *gwlist_consume(List *list);
00274 
00275 
00276 /*
00277  * Remove an item from the list, or return NULL if the list was empty
00278  * and there were no producers. If the list is empty but there are
00279  * producers, sleep until there is something to return or timeout occur.
00280  */
00281 void *gwlist_timed_consume(List *list, long sec);
00282 
00283 
00284 /*
00285  * Search the list for a particular item. If not found, return NULL. If found,
00286  * return the list element. Compare items to search pattern with 
00287  * `cmp(item, pattern)'. If the function returns non-zero, the items are 
00288  * equal.
00289  */
00290 void *gwlist_search(List *list, void *pattern, gwlist_item_matches_t *cmp);
00291 
00292 
00293 /*
00294  * Search the list for all items matching a pattern. If not found, return 
00295  * NULL. If found, return a list with the matching elements. Compare items
00296  * to search pattern with `cmp(item, pattern)'. If the function returns 
00297  * non-zero, the items are equal.
00298  */
00299 List *gwlist_search_all(List *list, void *pattern, gwlist_item_matches_t *cmp);
00300 
00301 
00302 /*
00303  * Sort the list with qsort.
00304  * if you have a list that you feed like that: 
00305  * Msg *message;
00306  * gwlist_add(mylist, message); 
00307  * a function that could sort messages by their data length would look like that:
00308  * int sort_by_messagelength(void* first_msg_pp, void* second_msg_pp)
00309  * {
00310  *     Msg *first_msg=*(Msg**)first_msg_pp;
00311  *     Msg *second_msg=*(Msg**)second_msg_pp;
00312  *     return octstr_len(first_msg->sms.msgdata) - octstr_len(second_msg->sms.msgdata);
00313  * }
00314  */
00315 void gwlist_sort(List *list, int(*cmp)(const void *, const void *));
00316 
00317 #endif
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.