Making the library more thread aware. This is an attempt to be Cancel-safe
or at least cancel friendly.
Showing
12 changed files
with
513 additions
and
172 deletions
... | @@ -21,13 +21,39 @@ | ... | @@ -21,13 +21,39 @@ |
21 | 21 | ||
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <string.h> | ||
25 | #ifdef HAVE_PTHREAD_H | ||
26 | # include <pthread.h> | ||
27 | #endif | ||
24 | 28 | ||
25 | #include <mailutils/registrar.h> | 29 | #include <mailutils/registrar.h> |
26 | #include <mailutils/iterator.h> | 30 | #include <mailutils/iterator.h> |
31 | #include <mailutils/list.h> | ||
27 | 32 | ||
28 | #include <misc.h> | 33 | #include <misc.h> |
29 | #include <folder0.h> | 34 | #include <folder0.h> |
30 | 35 | ||
36 | #ifdef WITH_PTHREAD | ||
37 | static pthread_mutex_t slock = PTHREAD_MUTEX_INITIALIZER; | ||
38 | #endif | ||
39 | |||
40 | /* Internal folder list. */ | ||
41 | static list_t known_folder_list; | ||
42 | static int is_known_folder (url_t, folder_t *); | ||
43 | static int is_same_scheme (url_t, url_t); | ||
44 | static int is_same_user (url_t, url_t); | ||
45 | static int is_same_path (url_t, url_t); | ||
46 | static int is_same_host (url_t, url_t); | ||
47 | static int is_same_port (url_t, url_t); | ||
48 | |||
49 | /* A folder could be a remote one, IMAP, or local, a spool directory | ||
50 | like $HOME/Mail etc .. We maintain a known list of folder to | ||
51 | not generate multiple folder of the same URL. Meaning when | ||
52 | folder_create () is call we'll check if we already have a | ||
53 | folder for that URL and return the same, if not we create a new one. | ||
54 | The downside, the algo to detect the same URL is very weak, and | ||
55 | they maybe cases where you want a different folder for the same | ||
56 | URL, there is not easy way to do this. */ | ||
31 | int | 57 | int |
32 | folder_create (folder_t *pfolder, const char *name) | 58 | folder_create (folder_t *pfolder, const char *name) |
33 | { | 59 | { |
... | @@ -41,7 +67,7 @@ folder_create (folder_t *pfolder, const char *name) | ... | @@ -41,7 +67,7 @@ folder_create (folder_t *pfolder, const char *name) |
41 | if (pfolder == NULL) | 67 | if (pfolder == NULL) |
42 | return EINVAL; | 68 | return EINVAL; |
43 | 69 | ||
44 | /* Look in the registrar, for a match */ | 70 | /* Look in the registrar list(iterator), for a match */ |
45 | registrar_get_list (&list); | 71 | registrar_get_list (&list); |
46 | status = iterator_create (&iterator, list); | 72 | status = iterator_create (&iterator, list); |
47 | if (status != 0) | 73 | if (status != 0) |
... | @@ -67,38 +93,63 @@ folder_create (folder_t *pfolder, const char *name) | ... | @@ -67,38 +93,63 @@ folder_create (folder_t *pfolder, const char *name) |
67 | url_t url = NULL; | 93 | url_t url = NULL; |
68 | folder_t folder = NULL; | 94 | folder_t folder = NULL; |
69 | 95 | ||
70 | /* Allocate memory for mbox. */ | ||
71 | folder = calloc (1, sizeof (*folder)); | ||
72 | if (folder == NULL) | ||
73 | return ENOMEM; | ||
74 | |||
75 | /* Initialize the internal lock, now so the concrete mailbox | ||
76 | could use it. */ | ||
77 | status = RWLOCK_INIT (&(folder->rwlock), NULL); | ||
78 | if (status != 0) | ||
79 | { | ||
80 | folder_destroy (&folder); | ||
81 | return status; | ||
82 | } | ||
83 | |||
84 | /* Parse the url, it may be a bad one and we should bailout if this | 96 | /* Parse the url, it may be a bad one and we should bailout if this |
85 | failed. */ | 97 | failed. */ |
86 | if ((status = url_create (&url, name)) != 0 | 98 | if ((status = url_create (&url, name) != 0) |
87 | || (status = entry->_url_init (url)) != 0) | 99 | || (status = entry->_url_init (url)) != 0) |
88 | { | 100 | return status; |
89 | folder_destroy (&folder); | ||
90 | return status; | ||
91 | } | ||
92 | folder->url = url; | ||
93 | 101 | ||
94 | /* Create the concrete folder type. */ | 102 | #ifdef WITH_PTHREAD |
95 | status = entry->_folder_init (folder); | 103 | pthread_mutex_lock (&slock); |
96 | if (status != 0) | 104 | #endif |
97 | { | 105 | /* Check if we already have the same URL folder. */ |
98 | folder_destroy (&folder); | 106 | if (is_known_folder (url, &folder)) |
99 | } | 107 | { |
108 | folder->ref++; | ||
109 | *pfolder = folder; | ||
110 | url_destroy (&url); | ||
111 | #ifdef WITH_PTHREAD | ||
112 | pthread_mutex_unlock (&slock); | ||
113 | #endif | ||
114 | return 0; | ||
115 | } | ||
116 | #ifdef WITH_PTHREAD | ||
100 | else | 117 | else |
101 | *pfolder = folder; | 118 | pthread_mutex_unlock (&slock); |
119 | #endif | ||
120 | |||
121 | /* Create a new folder. */ | ||
122 | |||
123 | /* Allocate memory for folder. */ | ||
124 | folder = calloc (1, sizeof (*folder)); | ||
125 | if (folder != NULL) | ||
126 | { | ||
127 | folder->url = url; | ||
128 | /* Initialize the internal lock, now so the concrete | ||
129 | folder could use it. */ | ||
130 | status = monitor_create (&(folder->monitor), folder); | ||
131 | if (status == 0) | ||
132 | { | ||
133 | /* Create the concrete folder type. */ | ||
134 | status = entry->_folder_init (folder); | ||
135 | if (status == 0) | ||
136 | { | ||
137 | *pfolder = folder; | ||
138 | folder->ref++; | ||
139 | /* Put on the internal list of known folders. */ | ||
140 | list_append (known_folder_list, folder); | ||
141 | } | ||
142 | } | ||
143 | /* Something went wrong, destroy the object. */ | ||
144 | if (status != 0) | ||
145 | { | ||
146 | if (folder->monitor) | ||
147 | monitor_destroy (&(folder->monitor), folder); | ||
148 | if (folder->url) | ||
149 | url_destroy (&(folder->url)); | ||
150 | free (folder); | ||
151 | } | ||
152 | } | ||
102 | } | 153 | } |
103 | else | 154 | else |
104 | status = ENOENT; | 155 | status = ENOENT; |
... | @@ -113,13 +164,26 @@ folder_destroy (folder_t *pfolder) | ... | @@ -113,13 +164,26 @@ folder_destroy (folder_t *pfolder) |
113 | { | 164 | { |
114 | folder_t folder = *pfolder; | 165 | folder_t folder = *pfolder; |
115 | int destroy_lock = 0; | 166 | int destroy_lock = 0; |
167 | monitor_t monitor = folder->monitor; | ||
168 | size_t reference; | ||
169 | |||
170 | monitor_wrlock (monitor); | ||
116 | #ifdef WITH_PTHREAD | 171 | #ifdef WITH_PTHREAD |
117 | pthread_rwlock_t rwlock = folder->rwlock; | 172 | pthread_mutex_lock (&slock); |
118 | #endif | 173 | #endif |
119 | RWLOCK_WRLOCK (&(rwlock)); | 174 | { |
120 | if (folder_decremente (folder) == 0) | 175 | folder->ref--; |
176 | reference = folder->ref; | ||
177 | /* Remove the folder from the list of known folder. */ | ||
178 | if (reference == 0) | ||
179 | list_remove (known_folder_list, folder); | ||
180 | } | ||
181 | #ifdef WITH_PHTREAD | ||
182 | pthread_mutex_unlock (&slock); | ||
183 | #endif | ||
184 | if (reference == 0) | ||
121 | { | 185 | { |
122 | RWLOCK_UNLOCK (&(rwlock)); | 186 | monitor_unlock (monitor); |
123 | destroy_lock = 1; | 187 | destroy_lock = 1; |
124 | /* Notify the observers. */ | 188 | /* Notify the observers. */ |
125 | if (folder->observable) | 189 | if (folder->observable) |
... | @@ -129,7 +193,7 @@ folder_destroy (folder_t *pfolder) | ... | @@ -129,7 +193,7 @@ folder_destroy (folder_t *pfolder) |
129 | } | 193 | } |
130 | if (folder->_destroy) | 194 | if (folder->_destroy) |
131 | folder->_destroy (folder); | 195 | folder->_destroy (folder); |
132 | RWLOCK_WRLOCK (&(rwlock)); | 196 | monitor_wrlock (monitor); |
133 | if (folder->ticket) | 197 | if (folder->ticket) |
134 | ticket_destroy (&(folder->ticket), folder); | 198 | ticket_destroy (&(folder->ticket), folder); |
135 | if (folder->authority) | 199 | if (folder->authority) |
... | @@ -140,9 +204,9 @@ folder_destroy (folder_t *pfolder) | ... | @@ -140,9 +204,9 @@ folder_destroy (folder_t *pfolder) |
140 | url_destroy (&(folder->url)); | 204 | url_destroy (&(folder->url)); |
141 | free (folder); | 205 | free (folder); |
142 | } | 206 | } |
143 | RWLOCK_UNLOCK (&(rwlock)); | 207 | monitor_unlock (monitor); |
144 | if (destroy_lock) | 208 | if (destroy_lock) |
145 | RWLOCK_DESTROY (&(rwlock)); | 209 | monitor_destroy (&monitor, folder); |
146 | *pfolder = NULL; | 210 | *pfolder = NULL; |
147 | } | 211 | } |
148 | } | 212 | } |
... | @@ -281,10 +345,144 @@ folder_delete_mailbox (folder_t folder, const char *name) | ... | @@ -281,10 +345,144 @@ folder_delete_mailbox (folder_t folder, const char *name) |
281 | return folder->_delete_mailbox (folder, name); | 345 | return folder->_delete_mailbox (folder, name); |
282 | } | 346 | } |
283 | 347 | ||
284 | int | 348 | static int is_known_folder (url_t url, folder_t *pfolder) |
285 | folder_decremente (folder_t folder) | 349 | { |
350 | int ret = 0; | ||
351 | folder_t folder = NULL; | ||
352 | iterator_t iterator; | ||
353 | |||
354 | if (url == NULL || pfolder == NULL) | ||
355 | return ret; | ||
356 | |||
357 | if (iterator_create (&iterator, known_folder_list) != 0) | ||
358 | return ret; | ||
359 | |||
360 | for (iterator_first (iterator); !iterator_is_done (iterator); | ||
361 | iterator_next (iterator)) | ||
362 | { | ||
363 | iterator_current (iterator, (void **)&folder); | ||
364 | /* Check if the same URL type. */ | ||
365 | if (folder && folder->url | ||
366 | && is_same_scheme (url, folder->url) | ||
367 | && is_same_user (url, folder->url) | ||
368 | && is_same_path (url, folder->url) | ||
369 | && is_same_host (url, folder->url) | ||
370 | && is_same_port (url, folder->url)) | ||
371 | { | ||
372 | ret = 1; | ||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | iterator_destroy (&iterator); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | static int | ||
381 | is_same_scheme (url_t url1, url_t url2) | ||
286 | { | 382 | { |
287 | if (folder && folder->_decremente) | 383 | int i = 0, j = 0; |
288 | return folder->_decremente (folder); | 384 | char *s1, *s2; |
289 | return (folder->ref--); | 385 | int ret = 1; |
386 | |||
387 | url_get_scheme (url1, NULL, 0, &i); | ||
388 | url_get_scheme (url2, NULL, 0, &j); | ||
389 | s1 = calloc (i + 1, sizeof (char)); | ||
390 | if (s1) | ||
391 | { | ||
392 | url_get_scheme (url1, s1, i + 1, NULL); | ||
393 | s2 = calloc (j + 1, sizeof (char)); | ||
394 | if (s2) | ||
395 | { | ||
396 | url_get_scheme (url2, s2, j + 1, NULL); | ||
397 | ret = !strcasecmp (s1, s2); | ||
398 | free (s2); | ||
399 | } | ||
400 | free (s1); | ||
401 | } | ||
402 | return ret; | ||
403 | } | ||
404 | |||
405 | static int | ||
406 | is_same_user (url_t url1, url_t url2) | ||
407 | { | ||
408 | int i = 0, j = 0; | ||
409 | char *s1, *s2; | ||
410 | int ret = 0; | ||
411 | |||
412 | url_get_user (url1, NULL, 0, &i); | ||
413 | url_get_user (url2, NULL, 0, &j); | ||
414 | s1 = calloc (i + 1, sizeof (char)); | ||
415 | if (s1) | ||
416 | { | ||
417 | url_get_user (url1, s1, i + 1, NULL); | ||
418 | s2 = calloc (j + 1, sizeof (char)); | ||
419 | if (s2) | ||
420 | { | ||
421 | url_get_user (url2, s2, j + 1, NULL); | ||
422 | ret = !strcasecmp (s1, s2); | ||
423 | free (s2); | ||
424 | } | ||
425 | free (s1); | ||
426 | } | ||
427 | return ret; | ||
428 | } | ||
429 | |||
430 | static int | ||
431 | is_same_path (url_t url1, url_t url2) | ||
432 | { | ||
433 | int i = 0, j = 0; | ||
434 | char *s1, *s2; | ||
435 | int ret = 0; | ||
436 | |||
437 | url_get_path (url1, NULL, 0, &i); | ||
438 | url_get_path (url2, NULL, 0, &j); | ||
439 | s1 = calloc (i + 1, sizeof (char)); | ||
440 | if (s1) | ||
441 | { | ||
442 | url_get_path (url1, s1, i + 1, NULL); | ||
443 | s2 = calloc (j + 1, sizeof (char)); | ||
444 | if (s2) | ||
445 | { | ||
446 | url_get_path (url2, s2, j + 1, NULL); | ||
447 | ret = !strcasecmp (s1, s2); | ||
448 | free (s2); | ||
449 | } | ||
450 | free (s1); | ||
451 | } | ||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | static int | ||
456 | is_same_host (url_t url1, url_t url2) | ||
457 | { | ||
458 | int i = 0, j = 0; | ||
459 | char *s1, *s2; | ||
460 | int ret = 0; | ||
461 | |||
462 | url_get_host (url1, NULL, 0, &i); | ||
463 | url_get_host (url2, NULL, 0, &j); | ||
464 | s1 = calloc (i + 1, sizeof (char)); | ||
465 | if (s1) | ||
466 | { | ||
467 | url_get_host (url1, s1, i + 1, NULL); | ||
468 | s2 = calloc (j + 1, sizeof (char)); | ||
469 | if (s2) | ||
470 | { | ||
471 | url_get_host (url2, s2, j + 1, NULL); | ||
472 | ret = !strcasecmp (s1, s2); | ||
473 | free (s2); | ||
474 | } | ||
475 | free (s1); | ||
476 | } | ||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | static int | ||
481 | is_same_port (url_t url1, url_t url2) | ||
482 | { | ||
483 | long p1 = 0, p2 = 0; | ||
484 | |||
485 | url_get_port (url1, &p1); | ||
486 | url_get_port (url2, &p2); | ||
487 | return (p1 == p2); | ||
290 | } | 488 | } | ... | ... |
... | @@ -22,14 +22,10 @@ | ... | @@ -22,14 +22,10 @@ |
22 | # include <dmalloc.h> | 22 | # include <dmalloc.h> |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #ifdef HAVE_PTHREAD_H | ||
26 | # define __USE_UNIX98 /* ?? */ | ||
27 | # include <pthread.h> | ||
28 | #endif | ||
29 | |||
30 | #include <sys/types.h> | 25 | #include <sys/types.h> |
31 | #include <stdio.h> | 26 | #include <stdio.h> |
32 | 27 | ||
28 | #include <mailutils/monitor.h> | ||
33 | #include <mailutils/folder.h> | 29 | #include <mailutils/folder.h> |
34 | 30 | ||
35 | #ifdef __cplusplus | 31 | #ifdef __cplusplus |
... | @@ -52,15 +48,12 @@ struct _folder | ... | @@ -52,15 +48,12 @@ struct _folder |
52 | observable_t observable; | 48 | observable_t observable; |
53 | debug_t debug; | 49 | debug_t debug; |
54 | stream_t stream; | 50 | stream_t stream; |
51 | monitor_t monitor; | ||
55 | url_t url; | 52 | url_t url; |
56 | int flags; | 53 | int flags; |
57 | size_t ref; | 54 | size_t ref; |
58 | size_t uid; | 55 | size_t uid; |
59 | 56 | ||
60 | #ifdef WITH_PTHREAD | ||
61 | pthread_rwlock_t rwlock; | ||
62 | #endif | ||
63 | |||
64 | /* Back pointer to the specific mailbox */ | 57 | /* Back pointer to the specific mailbox */ |
65 | void *data; | 58 | void *data; |
66 | 59 | ||
... | @@ -73,13 +66,8 @@ struct _folder | ... | @@ -73,13 +66,8 @@ struct _folder |
73 | int (*_close) __P ((folder_t)); | 66 | int (*_close) __P ((folder_t)); |
74 | int (*_list) __P ((folder_t, list_t *)); | 67 | int (*_list) __P ((folder_t, list_t *)); |
75 | int (*_delete_mailbox) __P ((folder_t, const char *)); | 68 | int (*_delete_mailbox) __P ((folder_t, const char *)); |
76 | int (*_decremente) __P ((folder_t)); | ||
77 | }; | 69 | }; |
78 | 70 | ||
79 | /* To manipulate mailbox rwlock. */ | ||
80 | extern int folder_rdlock __P ((folder_t)); | ||
81 | extern int folder_wrlock __P ((folder_t)); | ||
82 | extern int folder_unlock __P ((folder_t)); | ||
83 | 71 | ||
84 | #ifdef __cplusplus | 72 | #ifdef __cplusplus |
85 | } | 73 | } | ... | ... |
... | @@ -22,13 +22,10 @@ | ... | @@ -22,13 +22,10 @@ |
22 | # include <dmalloc.h> | 22 | # include <dmalloc.h> |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #ifdef HAVE_PTHREAD_H | 25 | #include <sys/types.h> |
26 | # define __USE_UNIX98 /* ?? */ | ||
27 | # include <pthread.h> | ||
28 | #endif | ||
29 | 26 | ||
30 | #include <mailutils/list.h> | 27 | #include <mailutils/list.h> |
31 | #include <sys/types.h> | 28 | #include <mailutils/monitor.h> |
32 | 29 | ||
33 | 30 | ||
34 | #ifndef __P | 31 | #ifndef __P |
... | @@ -54,9 +51,7 @@ struct _list | ... | @@ -54,9 +51,7 @@ struct _list |
54 | { | 51 | { |
55 | struct list_data head; | 52 | struct list_data head; |
56 | size_t count; | 53 | size_t count; |
57 | #ifdef WITH_PTHREAD | 54 | monitor_t monitor; |
58 | pthread_rwlock_t rwlock; | ||
59 | #endif | ||
60 | }; | 55 | }; |
61 | 56 | ||
62 | 57 | ... | ... |
... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
31 | #include <stdio.h> | 31 | #include <stdio.h> |
32 | 32 | ||
33 | #include <mailutils/monitor.h> | ||
33 | #include <mailutils/mailbox.h> | 34 | #include <mailutils/mailbox.h> |
34 | #include <mailutils/folder.h> | 35 | #include <mailutils/folder.h> |
35 | 36 | ||
... | @@ -57,10 +58,7 @@ struct _mailbox | ... | @@ -57,10 +58,7 @@ struct _mailbox |
57 | url_t url; | 58 | url_t url; |
58 | folder_t folder; | 59 | folder_t folder; |
59 | int flags; | 60 | int flags; |
60 | 61 | monitor_t monitor; | |
61 | #ifdef WITH_PTHREAD | ||
62 | pthread_rwlock_t rwlock; | ||
63 | #endif | ||
64 | 62 | ||
65 | /* Back pointer to the specific mailbox */ | 63 | /* Back pointer to the specific mailbox */ |
66 | void *data; | 64 | void *data; |
... | @@ -86,11 +84,6 @@ struct _mailbox | ... | @@ -86,11 +84,6 @@ struct _mailbox |
86 | 84 | ||
87 | }; | 85 | }; |
88 | 86 | ||
89 | /* To manipulate mailbox rwlock. */ | ||
90 | extern int mailbox_rdlock __P ((mailbox_t)); | ||
91 | extern int mailbox_wrlock __P ((mailbox_t)); | ||
92 | extern int mailbox_unlock __P ((mailbox_t)); | ||
93 | |||
94 | #define MAILBOX_NOTIFY(mbox, type) \ | 87 | #define MAILBOX_NOTIFY(mbox, type) \ |
95 | if (mbox->observer) observer_notify (mbox->observer, type) | 88 | if (mbox->observer) observer_notify (mbox->observer, type) |
96 | 89 | ... | ... |
mailbox/include/monitor0.h
0 → 100644
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Library Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU Library General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #ifndef _MONITOR0_H | ||
19 | #define _MONITOR0_H | ||
20 | |||
21 | #ifdef DMALLOC | ||
22 | # include <dmalloc.h> | ||
23 | #endif | ||
24 | |||
25 | #ifdef HAVE_CONFIG_H | ||
26 | # include <config.h> | ||
27 | #endif | ||
28 | |||
29 | #include <sys/types.h> | ||
30 | #include <mailutils/monitor.h> | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "C" { | ||
34 | #endif | ||
35 | |||
36 | #ifndef __P | ||
37 | # if __STDC__ | ||
38 | # define __P(x) x | ||
39 | # else | ||
40 | # define __P(x) | ||
41 | # endif | ||
42 | #endif | ||
43 | |||
44 | #ifdef HAVE_PTHREAD_H | ||
45 | # define __USE_UNIX98 | ||
46 | # include <pthread.h> | ||
47 | #endif | ||
48 | |||
49 | #ifdef WITH_PTHREAD | ||
50 | # if 0 | ||
51 | # define RWLOCK_INIT(rwl, attr) pthread_mutex_init (rwl, attr) | ||
52 | # define RWLOCK_DESTROY(rwl) pthread_mutex_destroy (rwl) | ||
53 | # define RWLOCK_RDLOCK(rwl) pthread_mutex_lock (rwl) | ||
54 | # define RWLOCK_TRYRDLOCK(rwl) pthread_mutex_trylock (rwl) | ||
55 | # define RWLOCK_WRLOCK(rwl) pthread_mutex_lock (rwl) | ||
56 | # define RWLOCK_TRYWRLOCK(rwl) pthread_mutex_trylock (rwl) | ||
57 | # define RWLOCK_UNLOCK(rwl) pthread_mutex_unlock (rwl) | ||
58 | # else | ||
59 | # define RWLOCK_INIT(rwl, attr) pthread_rwlock_init (rwl, attr) | ||
60 | # define RWLOCK_DESTROY(rwl) pthread_rwlock_destroy (rwl) | ||
61 | # define RWLOCK_RDLOCK(rwl) pthread_rwlock_rdlock (rwl) | ||
62 | # define RWLOCK_TRYRDLOCK(rwl) pthread_rwlock_tryrdlock (rwl) | ||
63 | # define RWLOCK_WRLOCK(rwl) pthread_rwlock_wrlock (rwl) | ||
64 | # define RWLOCK_TRYWRLOCK(rwl) pthread_rwlock_trywrlock (rwl) | ||
65 | # define RWLOCK_UNLOCK(rwl) pthread_rwlock_unlock (rwl) | ||
66 | # endif | ||
67 | #else | ||
68 | # define RWLOCK_INIT(rwl, attr) 0 | ||
69 | # define RWLOCK_DESTROY(rwl) 0 | ||
70 | # define RWLOCK_RDLOCK(rwl) 0 | ||
71 | # define RWLOCK_TRYRDLOCK(rwl) 0 | ||
72 | # define RWLOCK_WRLOCK(rwl) 0 | ||
73 | # define RWLOCK_TRYWRLOCK(rwl) 0 | ||
74 | # define RWLOCK_UNLOCK(rwl) 0 | ||
75 | # define flockfile(arg) 0 | ||
76 | # define funlockfile(arg) 0 | ||
77 | #endif | ||
78 | |||
79 | struct _monitor | ||
80 | { | ||
81 | #ifdef WITH_PTHREAD | ||
82 | pthread_rwlock_t lock; | ||
83 | #else | ||
84 | int lock; | ||
85 | #endif | ||
86 | void *owner; | ||
87 | }; | ||
88 | |||
89 | #ifdef __cplusplus | ||
90 | } | ||
91 | #endif | ||
92 | |||
93 | #endif /* _MONITOR0_H */ |
... | @@ -22,7 +22,6 @@ | ... | @@ -22,7 +22,6 @@ |
22 | #include <errno.h> | 22 | #include <errno.h> |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | 24 | ||
25 | #include <misc.h> | ||
26 | #include <list0.h> | 25 | #include <list0.h> |
27 | 26 | ||
28 | int | 27 | int |
... | @@ -35,7 +34,7 @@ list_create (list_t *plist) | ... | @@ -35,7 +34,7 @@ list_create (list_t *plist) |
35 | list = calloc (sizeof (*list), 1); | 34 | list = calloc (sizeof (*list), 1); |
36 | if (list == NULL) | 35 | if (list == NULL) |
37 | return ENOMEM; | 36 | return ENOMEM; |
38 | status = RWLOCK_INIT (&(list->rwlock), NULL); | 37 | status = monitor_create (&(list->monitor), list); |
39 | if (status != 0) | 38 | if (status != 0) |
40 | { | 39 | { |
41 | free (list); | 40 | free (list); |
... | @@ -55,15 +54,15 @@ list_destroy (list_t *plist) | ... | @@ -55,15 +54,15 @@ list_destroy (list_t *plist) |
55 | list_t list = *plist; | 54 | list_t list = *plist; |
56 | struct list_data *current; | 55 | struct list_data *current; |
57 | struct list_data *previous; | 56 | struct list_data *previous; |
58 | RWLOCK_WRLOCK (&(list->rwlock)); | 57 | monitor_wrlock (list->monitor); |
59 | for (current = list->head.next; current != &(list->head);) | 58 | for (current = list->head.next; current != &(list->head);) |
60 | { | 59 | { |
61 | previous = current; | 60 | previous = current; |
62 | current = current->next; | 61 | current = current->next; |
63 | free (previous); | 62 | free (previous); |
64 | } | 63 | } |
65 | RWLOCK_UNLOCK (&(list->rwlock)); | 64 | monitor_unlock (list->monitor); |
66 | RWLOCK_DESTROY (&(list->rwlock)); | 65 | monitor_destroy (&(list->monitor), list); |
67 | free (list); | 66 | free (list); |
68 | *plist = NULL; | 67 | *plist = NULL; |
69 | } | 68 | } |
... | @@ -78,13 +77,13 @@ list_append (list_t list, void *item) | ... | @@ -78,13 +77,13 @@ list_append (list_t list, void *item) |
78 | if (ldata == NULL) | 77 | if (ldata == NULL) |
79 | return ENOMEM; | 78 | return ENOMEM; |
80 | ldata->item = item; | 79 | ldata->item = item; |
81 | RWLOCK_WRLOCK (&(list->rwlock)); | 80 | monitor_wrlock (list->monitor); |
82 | ldata->next = &(list->head); | 81 | ldata->next = &(list->head); |
83 | ldata->prev = list->head.prev; | 82 | ldata->prev = list->head.prev; |
84 | last->next = ldata; | 83 | last->next = ldata; |
85 | list->head.prev = ldata; | 84 | list->head.prev = ldata; |
86 | list->count++; | 85 | list->count++; |
87 | RWLOCK_UNLOCK (&(list->rwlock)); | 86 | monitor_unlock (list->monitor); |
88 | return 0; | 87 | return 0; |
89 | } | 88 | } |
90 | 89 | ||
... | @@ -97,13 +96,13 @@ list_prepend (list_t list, void *item) | ... | @@ -97,13 +96,13 @@ list_prepend (list_t list, void *item) |
97 | if (ldata == NULL) | 96 | if (ldata == NULL) |
98 | return ENOMEM; | 97 | return ENOMEM; |
99 | ldata->item = item; | 98 | ldata->item = item; |
100 | RWLOCK_WRLOCK (&(list->rwlock)); | 99 | monitor_wrlock (list->monitor); |
101 | ldata->prev = &(list->head); | 100 | ldata->prev = &(list->head); |
102 | ldata->next = list->head.next; | 101 | ldata->next = list->head.next; |
103 | first->prev = ldata; | 102 | first->prev = ldata; |
104 | list->head.next = ldata; | 103 | list->head.next = ldata; |
105 | list->count++; | 104 | list->count++; |
106 | RWLOCK_UNLOCK (&(list->rwlock)); | 105 | monitor_unlock (list->monitor); |
107 | return 0; | 106 | return 0; |
108 | } | 107 | } |
109 | 108 | ||
... | @@ -130,7 +129,7 @@ list_remove (list_t list, void *item) | ... | @@ -130,7 +129,7 @@ list_remove (list_t list, void *item) |
130 | struct list_data *current, *previous; | 129 | struct list_data *current, *previous; |
131 | if (list == NULL) | 130 | if (list == NULL) |
132 | return EINVAL; | 131 | return EINVAL; |
133 | RWLOCK_WRLOCK (&(list->rwlock)); | 132 | monitor_wrlock (list->monitor); |
134 | for (previous = &(list->head), current = list->head.next; | 133 | for (previous = &(list->head), current = list->head.next; |
135 | current != &(list->head); previous = current, current = current->next) | 134 | current != &(list->head); previous = current, current = current->next) |
136 | { | 135 | { |
... | @@ -140,11 +139,11 @@ list_remove (list_t list, void *item) | ... | @@ -140,11 +139,11 @@ list_remove (list_t list, void *item) |
140 | current->next->prev = previous; | 139 | current->next->prev = previous; |
141 | free (current); | 140 | free (current); |
142 | list->count--; | 141 | list->count--; |
143 | RWLOCK_UNLOCK (&(list->rwlock)); | 142 | monitor_unlock (list->monitor); |
144 | return 0; | 143 | return 0; |
145 | } | 144 | } |
146 | } | 145 | } |
147 | RWLOCK_UNLOCK (&(list->rwlock)); | 146 | monitor_unlock (list->monitor); |
148 | return ENOENT; | 147 | return ENOENT; |
149 | } | 148 | } |
150 | 149 | ||
... | @@ -155,17 +154,17 @@ list_get (list_t list, size_t index, void **pitem) | ... | @@ -155,17 +154,17 @@ list_get (list_t list, size_t index, void **pitem) |
155 | size_t count; | 154 | size_t count; |
156 | if (list == NULL || pitem == NULL) | 155 | if (list == NULL || pitem == NULL) |
157 | return EINVAL; | 156 | return EINVAL; |
158 | RWLOCK_RDLOCK (&(list->rwlock)); | 157 | monitor_rdlock (list->monitor); |
159 | for (current = list->head.next, count = 0; current != &(list->head); | 158 | for (current = list->head.next, count = 0; current != &(list->head); |
160 | current = current->next, count++) | 159 | current = current->next, count++) |
161 | { | 160 | { |
162 | if (count == index) | 161 | if (count == index) |
163 | { | 162 | { |
164 | *pitem = current->item; | 163 | *pitem = current->item; |
165 | RWLOCK_UNLOCK (&(list->rwlock)); | 164 | monitor_unlock (list->monitor); |
166 | return 0; | 165 | return 0; |
167 | } | 166 | } |
168 | } | 167 | } |
169 | RWLOCK_UNLOCK (&(list->rwlock)); | 168 | monitor_unlock (list->monitor); |
170 | return ENOENT; | 169 | return ENOENT; |
171 | } | 170 | } | ... | ... |
... | @@ -22,10 +22,8 @@ | ... | @@ -22,10 +22,8 @@ |
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <errno.h> | 23 | #include <errno.h> |
24 | 24 | ||
25 | #include <mailutils/locker.h> | ||
26 | #include <mailutils/iterator.h> | 25 | #include <mailutils/iterator.h> |
27 | #include <mailutils/registrar.h> | 26 | #include <mailutils/registrar.h> |
28 | #include <misc.h> | ||
29 | #include <mailbox0.h> | 27 | #include <mailbox0.h> |
30 | 28 | ||
31 | /* The Mailbox Factory. | 29 | /* The Mailbox Factory. |
... | @@ -77,9 +75,9 @@ mailbox_create (mailbox_t *pmbox, const char *name) | ... | @@ -77,9 +75,9 @@ mailbox_create (mailbox_t *pmbox, const char *name) |
77 | if (mbox == NULL) | 75 | if (mbox == NULL) |
78 | return ENOMEM; | 76 | return ENOMEM; |
79 | 77 | ||
80 | /* Initialize the internal lock, now so the concrete mailbox | 78 | /* Initialize the internal lock now, so the concrete mailbox |
81 | could use it. */ | 79 | could use it. */ |
82 | status = RWLOCK_INIT (&(mbox->rwlock), NULL); | 80 | status = monitor_create (&(mbox->monitor), mbox); |
83 | if (status != 0) | 81 | if (status != 0) |
84 | { | 82 | { |
85 | mailbox_destroy (&mbox); | 83 | mailbox_destroy (&mbox); |
... | @@ -117,9 +115,7 @@ mailbox_destroy (mailbox_t *pmbox) | ... | @@ -117,9 +115,7 @@ mailbox_destroy (mailbox_t *pmbox) |
117 | if (pmbox && *pmbox) | 115 | if (pmbox && *pmbox) |
118 | { | 116 | { |
119 | mailbox_t mbox = *pmbox; | 117 | mailbox_t mbox = *pmbox; |
120 | #ifdef WITH_PTHREAD | 118 | monitor_t monitor = mbox->monitor; |
121 | pthread_rwlock_t rwlock = mbox->rwlock; | ||
122 | #endif | ||
123 | 119 | ||
124 | /* Notify the observers. */ | 120 | /* Notify the observers. */ |
125 | if (mbox->observable) | 121 | if (mbox->observable) |
... | @@ -132,7 +128,7 @@ mailbox_destroy (mailbox_t *pmbox) | ... | @@ -132,7 +128,7 @@ mailbox_destroy (mailbox_t *pmbox) |
132 | if (mbox->_destroy) | 128 | if (mbox->_destroy) |
133 | mbox->_destroy (mbox); | 129 | mbox->_destroy (mbox); |
134 | 130 | ||
135 | RWLOCK_WRLOCK (&(rwlock)); | 131 | monitor_wrlock (monitor); |
136 | 132 | ||
137 | /* Nuke the stream and close it */ | 133 | /* Nuke the stream and close it */ |
138 | if (mbox->stream) | 134 | if (mbox->stream) |
... | @@ -161,8 +157,8 @@ mailbox_destroy (mailbox_t *pmbox) | ... | @@ -161,8 +157,8 @@ mailbox_destroy (mailbox_t *pmbox) |
161 | 157 | ||
162 | free (mbox); | 158 | free (mbox); |
163 | *pmbox = NULL; | 159 | *pmbox = NULL; |
164 | RWLOCK_UNLOCK (&(rwlock)); | 160 | monitor_unlock (monitor); |
165 | RWLOCK_DESTROY (&(rwlock)); | 161 | monitor_destroy (&monitor, mbox); |
166 | } | 162 | } |
167 | } | 163 | } |
168 | 164 | ||
... | @@ -317,7 +313,7 @@ mailbox_set_stream (mailbox_t mbox, stream_t stream) | ... | @@ -317,7 +313,7 @@ mailbox_set_stream (mailbox_t mbox, stream_t stream) |
317 | int | 313 | int |
318 | mailbox_get_stream (mailbox_t mbox, stream_t *pstream) | 314 | mailbox_get_stream (mailbox_t mbox, stream_t *pstream) |
319 | { | 315 | { |
320 | if (mbox == NULL || pstream == NULL) | 316 | if (mbox == NULL || pstream) |
321 | return EINVAL; | 317 | return EINVAL; |
322 | *pstream = mbox->stream; | 318 | *pstream = mbox->stream; |
323 | return 0; | 319 | return 0; |
... | @@ -364,42 +360,3 @@ mailbox_get_debug (mailbox_t mbox, debug_t *pdebug) | ... | @@ -364,42 +360,3 @@ mailbox_get_debug (mailbox_t mbox, debug_t *pdebug) |
364 | *pdebug = mbox->debug; | 360 | *pdebug = mbox->debug; |
365 | return 0; | 361 | return 0; |
366 | } | 362 | } |
367 | |||
368 | /* Mailbox Internal Locks. Put the name of the functions in parenteses To make | ||
369 | sure it will not be redefine by a macro. If the flags was non-blocking we | ||
370 | should not block on the lock, so we try with pthread_rwlock_try*lock(). */ | ||
371 | int | ||
372 | (mailbox_rdlock) (mailbox_t mbox) | ||
373 | { | ||
374 | #ifdef WITH_PTHREAD | ||
375 | int err = (mbox->flags & MU_STREAM_NONBLOCK) ? | ||
376 | RWLOCK_TRYRDLOCK (&(mbox->rwlock)) : | ||
377 | RWLOCK_RDLOCK (&(mbox->rwlock)) ; | ||
378 | if (err != 0 && err != EDEADLK) | ||
379 | return err; | ||
380 | #endif | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | int | ||
385 | (mailbox_wrlock) (mailbox_t mbox) | ||
386 | { | ||
387 | #ifdef WITH_PTHREAD | ||
388 | int err = (mbox->flags & MU_STREAM_NONBLOCK) ? | ||
389 | RWLOCK_TRYWRLOCK (&(mbox->rwlock)) : | ||
390 | RWLOCK_WRLOCK (&(mbox->rwlock)) ; | ||
391 | if (err != 0 && err != EDEADLK) | ||
392 | return err; | ||
393 | #endif | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | int | ||
398 | (mailbox_unlock) (mailbox_t mbox) | ||
399 | { | ||
400 | #ifdef WITH_PTHREAD | ||
401 | return RWLOCK_UNLOCK (&(mbox->rwlock)); | ||
402 | #else | ||
403 | return 0; | ||
404 | #endif | ||
405 | } | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -191,17 +191,17 @@ do \ | ... | @@ -191,17 +191,17 @@ do \ |
191 | do \ | 191 | do \ |
192 | { \ | 192 | { \ |
193 | int bailing = 0; \ | 193 | int bailing = 0; \ |
194 | mailbox_unlock (mbox); \ | 194 | monitor_unlock (mbox->monitor); \ |
195 | if (mbox->observable) \ | 195 | if (mbox->observable) \ |
196 | bailing = observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD); \ | 196 | bailing = observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD); \ |
197 | if (bailing != 0) \ | 197 | if (bailing != 0) \ |
198 | { \ | 198 | { \ |
199 | if (pcount) \ | 199 | if (pcount) \ |
200 | *pcount = (mud)->messages_count; \ | 200 | *pcount = (mud)->messages_count; \ |
201 | mbox_unlock (mbox); \ | 201 | locker_unlock (mbox->locker); \ |
202 | return EINTR; \ | 202 | return EINTR; \ |
203 | } \ | 203 | } \ |
204 | mailbox_wrlock (mbox); \ | 204 | monitor_wrlock (mbox->monitor); \ |
205 | } while (0); | 205 | } while (0); |
206 | 206 | ||
207 | /* Notification MBX_PROGRESS | 207 | /* Notification MBX_PROGRESS |
... | @@ -215,7 +215,7 @@ do \ | ... | @@ -215,7 +215,7 @@ do \ |
215 | { \ | 215 | { \ |
216 | { \ | 216 | { \ |
217 | int bailing = 0; \ | 217 | int bailing = 0; \ |
218 | mailbox_unlock (mbox); \ | 218 | monitor_unlock (mbox->monitor); \ |
219 | mud->messages_count--; \ | 219 | mud->messages_count--; \ |
220 | if (mbox->observable) \ | 220 | if (mbox->observable) \ |
221 | bailing = observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS); \ | 221 | bailing = observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS); \ |
... | @@ -223,11 +223,11 @@ do \ | ... | @@ -223,11 +223,11 @@ do \ |
223 | { \ | 223 | { \ |
224 | if (pcount) \ | 224 | if (pcount) \ |
225 | *pcount = (mud)->messages_count; \ | 225 | *pcount = (mud)->messages_count; \ |
226 | mbox_unlock (mbox); \ | 226 | locker_unlock (mbox->locker); \ |
227 | return EINTR; \ | 227 | return EINTR; \ |
228 | } \ | 228 | } \ |
229 | mud->messages_count++; \ | 229 | mud->messages_count++; \ |
230 | mailbox_wrlock (mbox); \ | 230 | monitor_wrlock (mbox->monitor); \ |
231 | } \ | 231 | } \ |
232 | } while (0) | 232 | } while (0) |
233 | 233 | ||
... | @@ -243,16 +243,16 @@ do \ | ... | @@ -243,16 +243,16 @@ do \ |
243 | m = realloc ((mud)->umessages, num * sizeof (*m)); \ | 243 | m = realloc ((mud)->umessages, num * sizeof (*m)); \ |
244 | if (m == NULL) \ | 244 | if (m == NULL) \ |
245 | { \ | 245 | { \ |
246 | mbox_unlock (mbox); \ | 246 | locker_unlock (mbox->locker); \ |
247 | mailbox_unlock (mbox); \ | 247 | monitor_unlock (mbox->monitor); \ |
248 | return ENOMEM; \ | 248 | return ENOMEM; \ |
249 | } \ | 249 | } \ |
250 | (mud)->umessages = m; \ | 250 | (mud)->umessages = m; \ |
251 | (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \ | 251 | (mud)->umessages[num - 1] = calloc (1, sizeof (*(mum))); \ |
252 | if ((mud)->umessages[num - 1] == NULL) \ | 252 | if ((mud)->umessages[num - 1] == NULL) \ |
253 | { \ | 253 | { \ |
254 | mbox_unlock (mbox); \ | 254 | locker_unlock (mbox->locker); \ |
255 | mailbox_unlock (mbox); \ | 255 | monitor_unlock (mbox->monitor); \ |
256 | return ENOMEM; \ | 256 | return ENOMEM; \ |
257 | } \ | 257 | } \ |
258 | (mud)->umessages_count = num; \ | 258 | (mud)->umessages_count = num; \ |
... | @@ -282,17 +282,23 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -282,17 +282,23 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
282 | return EINVAL; | 282 | return EINVAL; |
283 | 283 | ||
284 | /* Grab the lock. */ | 284 | /* Grab the lock. */ |
285 | mailbox_wrlock (mailbox); | 285 | monitor_wrlock (mailbox->monitor); |
286 | |||
287 | #ifdef WITH_PTHREAD | ||
288 | /* read() is cancellation point since we're doing a potentially | ||
289 | long operation. Lets make sure we clean the state. */ | ||
290 | pthread_cleanup_push (mbox_cleanup, (void *)mailbox); | ||
291 | #endif | ||
286 | 292 | ||
287 | /* Save the timestamp and size. */ | 293 | /* Save the timestamp and size. */ |
288 | status = stream_size (mailbox->stream, &(mud->size)); | 294 | status = stream_size (mailbox->stream, &(mud->size)); |
289 | if (status != 0) | 295 | if (status != 0) |
290 | { | 296 | { |
291 | mailbox_unlock (mailbox); | 297 | monitor_unlock (mailbox->monitor); |
292 | return status; | 298 | return status; |
293 | } | 299 | } |
294 | 300 | ||
295 | mbox_lock (mailbox, MU_LOCKER_RDLOCK); | 301 | locker_lock (mailbox->locker, MU_LOCKER_RDLOCK); |
296 | 302 | ||
297 | /* Seek to the starting point. */ | 303 | /* Seek to the starting point. */ |
298 | if (mud->umessages && msgno > 0 && mud->messages_count > 0 | 304 | if (mud->umessages && msgno > 0 && mud->messages_count > 0 |
... | @@ -376,7 +382,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -376,7 +382,7 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
376 | 382 | ||
377 | /* Every 50 mesgs update the lock, it should be every minute. */ | 383 | /* Every 50 mesgs update the lock, it should be every minute. */ |
378 | if ((mud->messages_count % 50) == 0) | 384 | if ((mud->messages_count % 50) == 0) |
379 | mbox_touchlock (mailbox); | 385 | locker_touchlock (mailbox->locker); |
380 | 386 | ||
381 | /* Ping them every 1000 lines. */ | 387 | /* Ping them every 1000 lines. */ |
382 | if (do_notif) | 388 | if (do_notif) |
... | @@ -392,9 +398,13 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) | ... | @@ -392,9 +398,13 @@ mbox_scan0 (mailbox_t mailbox, size_t msgno, size_t *pcount, int do_notif) |
392 | if (do_notif) | 398 | if (do_notif) |
393 | DISPATCH_ADD_MSG(mailbox, mud); | 399 | DISPATCH_ADD_MSG(mailbox, mud); |
394 | } | 400 | } |
395 | mbox_unlock (mailbox); | ||
396 | if (pcount) | 401 | if (pcount) |
397 | *pcount = mud->messages_count; | 402 | *pcount = mud->messages_count; |
398 | mailbox_unlock (mailbox); | 403 | locker_unlock (mailbox->locker); |
404 | monitor_unlock (mailbox->monitor); | ||
405 | |||
406 | #ifdef WITH_PTHREAD | ||
407 | pthread_cleanup_pop (0); | ||
408 | #endif | ||
399 | return status; | 409 | return status; |
400 | } | 410 | } | ... | ... |
... | @@ -189,7 +189,7 @@ struct _pop_data | ... | @@ -189,7 +189,7 @@ struct _pop_data |
189 | #define CHECK_BUSY(mbox, mpd, function, identity) \ | 189 | #define CHECK_BUSY(mbox, mpd, function, identity) \ |
190 | do \ | 190 | do \ |
191 | { \ | 191 | { \ |
192 | int err = mailbox_wrlock (mbox); \ | 192 | int err = monitor_wrlock (mbox->monitor); \ |
193 | if (err != 0) \ | 193 | if (err != 0) \ |
194 | return err; \ | 194 | return err; \ |
195 | if ((mpd->func && mpd->func != function) \ | 195 | if ((mpd->func && mpd->func != function) \ |
... | @@ -198,7 +198,7 @@ do \ | ... | @@ -198,7 +198,7 @@ do \ |
198 | mpd->id = 0; \ | 198 | mpd->id = 0; \ |
199 | mpd->func = pop_open; \ | 199 | mpd->func = pop_open; \ |
200 | mpd->state = POP_NO_STATE; \ | 200 | mpd->state = POP_NO_STATE; \ |
201 | mailbox_unlock (mbox); \ | 201 | monitor_unlock (mbox->monitor); \ |
202 | err = pop_open (mbox, mbox->flags); \ | 202 | err = pop_open (mbox, mbox->flags); \ |
203 | if (err != 0) \ | 203 | if (err != 0) \ |
204 | { \ | 204 | { \ |
... | @@ -209,7 +209,7 @@ do \ | ... | @@ -209,7 +209,7 @@ do \ |
209 | { \ | 209 | { \ |
210 | mpd->id = (size_t)identity; \ | 210 | mpd->id = (size_t)identity; \ |
211 | mpd->func = func; \ | 211 | mpd->func = func; \ |
212 | mailbox_unlock (mbox); \ | 212 | monitor_unlock (mbox->monitor); \ |
213 | } \ | 213 | } \ |
214 | } \ | 214 | } \ |
215 | while (0) | 215 | while (0) |
... | @@ -301,7 +301,7 @@ pop_destroy (mailbox_t mbox) | ... | @@ -301,7 +301,7 @@ pop_destroy (mailbox_t mbox) |
301 | { | 301 | { |
302 | pop_data_t mpd = mbox->data; | 302 | pop_data_t mpd = mbox->data; |
303 | size_t i; | 303 | size_t i; |
304 | mailbox_wrlock (mbox); | 304 | monitor_wrlock (mbox->monitor); |
305 | /* Destroy the pop messages and ressources associated to them. */ | 305 | /* Destroy the pop messages and ressources associated to them. */ |
306 | for (i = 0; i < mpd->pmessages_count; i++) | 306 | for (i = 0; i < mpd->pmessages_count; i++) |
307 | { | 307 | { |
... | @@ -320,7 +320,7 @@ pop_destroy (mailbox_t mbox) | ... | @@ -320,7 +320,7 @@ pop_destroy (mailbox_t mbox) |
320 | free (mpd->pmessages); | 320 | free (mpd->pmessages); |
321 | free (mpd); | 321 | free (mpd); |
322 | mbox->data = NULL; | 322 | mbox->data = NULL; |
323 | mailbox_unlock (mbox); | 323 | monitor_unlock (mbox->monitor); |
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
... | @@ -545,12 +545,12 @@ pop_close (mailbox_t mbox) | ... | @@ -545,12 +545,12 @@ pop_close (mailbox_t mbox) |
545 | return EINVAL; | 545 | return EINVAL; |
546 | 546 | ||
547 | /* CHECK_BUSY (mbox, mpd, func, 0); */ | 547 | /* CHECK_BUSY (mbox, mpd, func, 0); */ |
548 | mailbox_wrlock (mbox); | 548 | monitor_wrlock (mbox->monitor); |
549 | if (mpd->func && mpd->func != func) | 549 | if (mpd->func && mpd->func != func) |
550 | mpd->state = POP_NO_STATE; | 550 | mpd->state = POP_NO_STATE; |
551 | mpd->id = 0; | 551 | mpd->id = 0; |
552 | mpd->func = func; | 552 | mpd->func = func; |
553 | mailbox_unlock (mbox); | 553 | monitor_unlock (mbox->monitor); |
554 | 554 | ||
555 | /* Ok boys, it's a wrap: UPDATE State. */ | 555 | /* Ok boys, it's a wrap: UPDATE State. */ |
556 | switch (mpd->state) | 556 | switch (mpd->state) |
... | @@ -625,7 +625,7 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) | ... | @@ -625,7 +625,7 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
625 | if (pmsg == NULL || mpd == NULL) | 625 | if (pmsg == NULL || mpd == NULL) |
626 | return EINVAL; | 626 | return EINVAL; |
627 | 627 | ||
628 | mailbox_rdlock (mbox); | 628 | monitor_rdlock (mbox->monitor); |
629 | /* See if we have already this message. */ | 629 | /* See if we have already this message. */ |
630 | for (i = 0; i < mpd->pmessages_count; i++) | 630 | for (i = 0; i < mpd->pmessages_count; i++) |
631 | { | 631 | { |
... | @@ -634,12 +634,12 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) | ... | @@ -634,12 +634,12 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
634 | if (mpd->pmessages[i]->num == msgno) | 634 | if (mpd->pmessages[i]->num == msgno) |
635 | { | 635 | { |
636 | *pmsg = mpd->pmessages[i]->message; | 636 | *pmsg = mpd->pmessages[i]->message; |
637 | mailbox_unlock (mbox); | 637 | monitor_unlock (mbox->monitor); |
638 | return 0; | 638 | return 0; |
639 | } | 639 | } |
640 | } | 640 | } |
641 | } | 641 | } |
642 | mailbox_unlock (mbox); | 642 | monitor_unlock (mbox->monitor); |
643 | 643 | ||
644 | mpm = calloc (1, sizeof (*mpm)); | 644 | mpm = calloc (1, sizeof (*mpm)); |
645 | if (mpm == NULL) | 645 | if (mpm == NULL) |
... | @@ -724,7 +724,7 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) | ... | @@ -724,7 +724,7 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
724 | message_set_uidl (msg, pop_uidl, mpm); | 724 | message_set_uidl (msg, pop_uidl, mpm); |
725 | 725 | ||
726 | /* Add it to the list. */ | 726 | /* Add it to the list. */ |
727 | mailbox_wrlock (mbox); | 727 | monitor_wrlock (mbox->monitor); |
728 | { | 728 | { |
729 | pop_message_t *m ; | 729 | pop_message_t *m ; |
730 | m = realloc (mpd->pmessages, (mpd->pmessages_count + 1)*sizeof (*m)); | 730 | m = realloc (mpd->pmessages, (mpd->pmessages_count + 1)*sizeof (*m)); |
... | @@ -732,14 +732,14 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) | ... | @@ -732,14 +732,14 @@ pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg) |
732 | { | 732 | { |
733 | message_destroy (&msg, mpm); | 733 | message_destroy (&msg, mpm); |
734 | free (mpm); | 734 | free (mpm); |
735 | mailbox_unlock (mbox); | 735 | monitor_unlock (mbox->monitor); |
736 | return ENOMEM; | 736 | return ENOMEM; |
737 | } | 737 | } |
738 | mpd->pmessages = m; | 738 | mpd->pmessages = m; |
739 | mpd->pmessages[mpd->pmessages_count] = mpm; | 739 | mpd->pmessages[mpd->pmessages_count] = mpm; |
740 | mpd->pmessages_count++; | 740 | mpd->pmessages_count++; |
741 | } | 741 | } |
742 | mailbox_unlock (mbox); | 742 | monitor_unlock (mbox->monitor); |
743 | 743 | ||
744 | /* Save The message. */ | 744 | /* Save The message. */ |
745 | *pmsg = mpm->message = msg; | 745 | *pmsg = mpm->message = msg; | ... | ... |
... | @@ -21,6 +21,8 @@ | ... | @@ -21,6 +21,8 @@ |
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <ctype.h> | 23 | #include <ctype.h> |
24 | #include <unistd.h> | ||
25 | #include <time.h> | ||
24 | 26 | ||
25 | #include <mailutils/message.h> | 27 | #include <mailutils/message.h> |
26 | #include <mailutils/stream.h> | 28 | #include <mailutils/stream.h> |
... | @@ -371,7 +373,7 @@ static int _mime_set_content_type(mime_t mime) | ... | @@ -371,7 +373,7 @@ static int _mime_set_content_type(mime_t mime) |
371 | char boundary[128]; | 373 | char boundary[128]; |
372 | header_t hdr = NULL; | 374 | header_t hdr = NULL; |
373 | size_t size; | 375 | size_t size; |
374 | 376 | ||
375 | if ( mime->nmtp_parts > 1 ) { | 377 | if ( mime->nmtp_parts > 1 ) { |
376 | if ( mime->flags & MIME_ADDED_MULTIPART_CT ) | 378 | if ( mime->flags & MIME_ADDED_MULTIPART_CT ) |
377 | return 0; | 379 | return 0; |
... | @@ -453,7 +455,7 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, | ... | @@ -453,7 +455,7 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, |
453 | } | 455 | } |
454 | while(mime->postamble) { | 456 | while(mime->postamble) { |
455 | mime->postamble--; | 457 | mime->postamble--; |
456 | ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes); | 458 | ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes); |
457 | } | 459 | } |
458 | mime->flags &= ~(MIME_INSERT_BOUNDARY|MIME_ADDING_BOUNDARY); | 460 | mime->flags &= ~(MIME_INSERT_BOUNDARY|MIME_ADDING_BOUNDARY); |
459 | mime->part_offset = 0; | 461 | mime->part_offset = 0; |
... | @@ -463,9 +465,9 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, | ... | @@ -463,9 +465,9 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, |
463 | return 0; | 465 | return 0; |
464 | message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream); | 466 | message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream); |
465 | } else { | 467 | } else { |
466 | body_t body; | 468 | body_t b; |
467 | message_get_body(mime->mtp_parts[mime->cur_part]->msg, &body); | 469 | message_get_body(mime->mtp_parts[mime->cur_part]->msg, &b); |
468 | body_get_stream(body, &msg_stream); | 470 | body_get_stream(b, &msg_stream); |
469 | } | 471 | } |
470 | ret = stream_read(msg_stream, buf, buflen, mime->part_offset, &part_nbytes ); | 472 | ret = stream_read(msg_stream, buf, buflen, mime->part_offset, &part_nbytes ); |
471 | len += part_nbytes; | 473 | len += part_nbytes; |
... | @@ -673,7 +675,7 @@ int mime_get_num_parts(mime_t mime, int *nmtp_parts) | ... | @@ -673,7 +675,7 @@ int mime_get_num_parts(mime_t mime, int *nmtp_parts) |
673 | int mime_add_part(mime_t mime, message_t msg) | 675 | int mime_add_part(mime_t mime, message_t msg) |
674 | { | 676 | { |
675 | int ret; | 677 | int ret; |
676 | 678 | ||
677 | if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 ) | 679 | if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 ) |
678 | return EINVAL; | 680 | return EINVAL; |
679 | if ( ( ret = _mime_append_part(mime, msg, 0, 0, 0) ) == 0 ) | 681 | if ( ( ret = _mime_append_part(mime, msg, 0, 0, 0) ) == 0 ) | ... | ... |
mailbox/monitor.c
0 → 100644
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Library Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU Library General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include <errno.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <monitor0.h> | ||
21 | |||
22 | int | ||
23 | monitor_create (monitor_t *pmonitor, void *owner) | ||
24 | { | ||
25 | monitor_t monitor; | ||
26 | int status = 0; | ||
27 | if (pmonitor == NULL) | ||
28 | return EINVAL; | ||
29 | monitor = calloc (1, sizeof (*monitor)); | ||
30 | if (monitor == NULL) | ||
31 | return ENOMEM; | ||
32 | monitor->owner = owner; | ||
33 | status = RWLOCK_INIT (&(monitor->lock), NULL); | ||
34 | if (status == 0) | ||
35 | { | ||
36 | free (monitor); | ||
37 | return status; | ||
38 | } | ||
39 | *pmonitor = monitor; | ||
40 | return status; | ||
41 | } | ||
42 | |||
43 | void * | ||
44 | monitor_get_owner (monitor_t monitor) | ||
45 | { | ||
46 | return (monitor == NULL) ? NULL : monitor->owner; | ||
47 | } | ||
48 | |||
49 | void | ||
50 | monitor_destroy (monitor_t *pmonitor, void *owner) | ||
51 | { | ||
52 | if (pmonitor && *pmonitor) | ||
53 | { | ||
54 | monitor_t monitor = *pmonitor; | ||
55 | if (monitor->owner == owner) | ||
56 | { | ||
57 | RWLOCK_DESTROY (&(monitor->lock)); | ||
58 | } | ||
59 | free (monitor); | ||
60 | *pmonitor = NULL; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | int | ||
65 | monitor_rdlock (monitor_t monitor) | ||
66 | { | ||
67 | if (monitor) | ||
68 | { | ||
69 | return RWLOCK_RDLOCK (&(monitor->lock)); | ||
70 | } | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int | ||
75 | monitor_wrlock (monitor_t monitor) | ||
76 | { | ||
77 | if (monitor) | ||
78 | { | ||
79 | return RWLOCK_WRLOCK (&(monitor->lock)); | ||
80 | } | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | int | ||
85 | monitor_unlock (monitor_t monitor) | ||
86 | { | ||
87 | if (monitor) | ||
88 | { | ||
89 | return RWLOCK_UNLOCK (&(monitor->lock)); | ||
90 | } | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | int | ||
95 | monitor_wait (monitor_t monitor) | ||
96 | { | ||
97 | (void)monitor; | ||
98 | return ENOSYS; | ||
99 | } | ||
100 | |||
101 | int | ||
102 | monitor_notify (monitor_t monitor) | ||
103 | { | ||
104 | (void)monitor; | ||
105 | return ENOSYS; | ||
106 | } |
-
Please register or sign in to post a comment