talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

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 }