1 /*
2 * Sylpheed -- 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 */
qryreq_clear(QueryRequest * req)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 */
qryreq_free(QueryRequest * req)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 */
qryreq_set_search_type(QueryRequest * req,const AddrSearchType value)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 */
qryreq_add_query(QueryRequest * req,AddrQueryObject * aqo)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 */
qrymgr_add_request(const gchar * searchTerm,void * callBackEnd,void * callBackEntry)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 */
qrymgr_find_request(const gint queryID)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 */
qrymgr_delete_request(const gint queryID)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 */
qrymgr_initialize(void)196 void qrymgr_initialize( void ) {
197 _requestList_ = NULL;
198 }
199
200 /**
201 * Free all queries.
202 */
qrymgr_free_all_request(void)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 */
qrymgr_teardown(void)223 void qrymgr_teardown( void ) {
224 qrymgr_free_all_request();
225 }
226
227 /*
228 * End of Source.
229 */
230
231
232