Commit 18406256 18406256a580340a70c9f5ef452f7b79621529d8 by Alain Magloire

Making the library more thread aware. This is an attempt to be Cancel-safe

or at least cancel friendly.
1 parent 06aea14d
...@@ -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
......
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 }
......
...@@ -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 )
......
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 }