addrquery.c (5195B)
1 /* 2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client 3 * Copyright (C) 2003-2012 Match Grun and the Claws Mail team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 /* 21 * Functions to define an address query (a request). 22 */ 23 24 #include <stdio.h> 25 #include <string.h> 26 #include <glib.h> 27 #include <pthread.h> 28 29 #include "mgutils.h" 30 #include "addrquery.h" 31 #include "utils.h" 32 33 /** 34 * Query list for tracking current queries. 35 */ 36 static GList *_requestList_ = NULL; 37 38 /** 39 * Mutex to protect list from multiple threads. 40 */ 41 static pthread_mutex_t _requestListMutex_ = PTHREAD_MUTEX_INITIALIZER; 42 43 /** 44 * Current query ID. This is incremented for each query request created. 45 */ 46 static gint _currentQueryID_ = 0; 47 48 /** 49 * Clear the query. 50 * \param req Request query object. 51 */ 52 static void qryreq_clear( QueryRequest *req ) { 53 GList *node; 54 55 cm_return_if_fail( req != NULL ); 56 g_free( req->searchTerm ); 57 req->queryID = 0; 58 req->searchType = ADDRSEARCH_NONE; 59 req->searchTerm = NULL; 60 req->callBackEnd = NULL; 61 req->callBackEntry = NULL; 62 63 /* Empty the list */ 64 node = req->queryList; 65 while( node ) { 66 node->data = NULL; 67 node = g_list_next( node ); 68 } 69 g_list_free( req->queryList ); 70 req->queryList = NULL; 71 } 72 73 /** 74 * Free query. 75 * \param req Request query object. 76 */ 77 static void qryreq_free( QueryRequest *req ) { 78 cm_return_if_fail( req != NULL ); 79 qryreq_clear( req ); 80 g_free( req ); 81 } 82 83 /** 84 * Specify search type. 85 * \param req Request query object. 86 * \param value Type. 87 */ 88 void qryreq_set_search_type( QueryRequest *req, const AddrSearchType value ) { 89 cm_return_if_fail( req != NULL ); 90 req->searchType = value; 91 } 92 93 /** 94 * Add address query object to request. 95 * \param req Request query object. 96 * \param aqo Address query object that performs the search. 97 */ 98 void qryreq_add_query( QueryRequest *req, AddrQueryObject *aqo ) { 99 cm_return_if_fail( req != NULL ); 100 cm_return_if_fail( aqo != NULL ); 101 req->queryList = g_list_append( req->queryList, aqo ); 102 } 103 104 /** 105 * Add query to list. 106 * 107 * \param searchTerm Search term. A private copy will be made. 108 * \param callBackEnd Callback function that will be called when query 109 * terminates. 110 * \param callBackEntry Callback function that will be called after each 111 * address entry has been read. 112 * \return Initialize query request object. 113 */ 114 QueryRequest *qrymgr_add_request( 115 const gchar *searchTerm, void *callBackEnd, void *callBackEntry ) 116 { 117 QueryRequest *req; 118 119 req = g_new0( QueryRequest, 1 ); 120 req->searchTerm = g_strdup( searchTerm ); 121 req->callBackEnd = callBackEnd; 122 req->callBackEntry = callBackEntry; 123 req->timeStart = time( NULL ); 124 req->queryList = NULL; 125 126 /* Insert in head of list */ 127 pthread_mutex_lock( & _requestListMutex_ ); 128 req->queryID = ++_currentQueryID_; 129 _requestList_ = g_list_prepend( _requestList_, req ); 130 pthread_mutex_unlock( & _requestListMutex_ ); 131 132 return req; 133 } 134 135 /** 136 * Find query in list. 137 * \param queryID ID of query to find. 138 * \return Query object, or <i>NULL</i> if not found. 139 */ 140 QueryRequest *qrymgr_find_request( const gint queryID ) { 141 QueryRequest *req; 142 QueryRequest *q; 143 GList *node; 144 145 pthread_mutex_lock( & _requestListMutex_ ); 146 req = NULL; 147 node = _requestList_; 148 while( node ) { 149 q = node->data; 150 if( q->queryID == queryID ) { 151 req = q; 152 break; 153 } 154 node = g_list_next( node ); 155 } 156 pthread_mutex_unlock( & _requestListMutex_ ); 157 158 return req; 159 } 160 161 /** 162 * Delete specified query. 163 * \param queryID ID of query to retire. 164 */ 165 void qrymgr_delete_request( const gint queryID ) { 166 QueryRequest *req; 167 GList *node, *nf; 168 169 pthread_mutex_lock( & _requestListMutex_ ); 170 171 /* Find node */ 172 nf = NULL; 173 node = _requestList_; 174 while( node ) { 175 req = node->data; 176 if( req->queryID == queryID ) { 177 nf = node; 178 qryreq_free( req ); 179 break; 180 } 181 node = g_list_next( node ); 182 } 183 184 /* Free link element and associated query */ 185 if( nf ) { 186 _requestList_ = g_list_remove_link( _requestList_, nf ); 187 g_list_free_1( nf ); 188 } 189 190 pthread_mutex_unlock( & _requestListMutex_ ); 191 } 192 193 /** 194 * Initialize query manager. 195 */ 196 void qrymgr_initialize( void ) { 197 _requestList_ = NULL; 198 } 199 200 /** 201 * Free all queries. 202 */ 203 static void qrymgr_free_all_request( void ) { 204 QueryRequest *req; 205 GList *node; 206 207 pthread_mutex_lock( & _requestListMutex_ ); 208 node = _requestList_; 209 while( node ) { 210 req = node->data; 211 qryreq_free( req ); 212 node->data = NULL; 213 node = g_list_next( node ); 214 } 215 g_list_free( _requestList_ ); 216 _requestList_ = NULL; 217 pthread_mutex_unlock( & _requestListMutex_ ); 218 } 219 220 /** 221 * Teardown query manager. 222 */ 223 void qrymgr_teardown( void ) { 224 qrymgr_free_all_request(); 225 }