Commit d50a2580 d50a25809b8017b2017e0dc4e112fe3e423d8008 by Alain Magloire

This is after an exchange with Dave Inglis and Sam Roberts.

	Basically they recommand to drop the XX_release() functions
	and only to keep XX_create (), XX_destroy ().  We have simple
	reference count strategy for memory management.

	* mailbox2/* : Way too much to enumerate.
	* mailbox2/refcount.c: New file
	* mailbox2/include/mailutils/refcount.h: New file
	* mailbox2/include/mailutils/sys/refcount.h: New file
	* mailbox2/fdstream.c: stream_fd_create ().
1 parent 48f314aa
Showing 84 changed files with 1469 additions and 1085 deletions
...@@ -15,8 +15,10 @@ libmailbox_la_SOURCES = \ ...@@ -15,8 +15,10 @@ libmailbox_la_SOURCES = \
15 attribute.c \ 15 attribute.c \
16 authority.c \ 16 authority.c \
17 bstream.c \ 17 bstream.c \
18 dattribute.c \
18 dotlock.c \ 19 dotlock.c \
19 envelope.c \ 20 envelope.c \
21 fdstream.c \
20 folder.c \ 22 folder.c \
21 fstream.c \ 23 fstream.c \
22 header.c \ 24 header.c \
...@@ -33,6 +35,7 @@ libmailbox_la_SOURCES = \ ...@@ -33,6 +35,7 @@ libmailbox_la_SOURCES = \
33 observer.c \ 35 observer.c \
34 parse822.c \ 36 parse822.c \
35 pticket.c \ 37 pticket.c \
38 refcount.c \
36 stream.c \ 39 stream.c \
37 tcpstream.c \ 40 tcpstream.c \
38 ticket.c 41 ticket.c
......
...@@ -54,19 +54,21 @@ address_create (address_t *a, const char *s) ...@@ -54,19 +54,21 @@ address_create (address_t *a, const char *s)
54 (*a)->addr = strdup (s); 54 (*a)->addr = strdup (s);
55 if (!(*a)->addr) 55 if (!(*a)->addr)
56 { 56 {
57 address_destroy (*a); 57 address_destroy (a);
58 return ENOMEM; 58 return ENOMEM;
59 } 59 }
60 } 60 }
61 return status; 61 return status;
62 } 62 }
63 63
64 int 64 void
65 address_destroy (address_t address) 65 address_destroy (address_t *paddress)
66 { 66 {
67 if (address) 67 if (paddress && *paddress)
68 { 68 {
69 address_t current; 69 address_t current;
70 address_t address = *paddress;
71
70 for (; address; address = current) 72 for (; address; address = current)
71 { 73 {
72 if (address->addr) 74 if (address->addr)
...@@ -86,8 +88,8 @@ address_destroy (address_t address) ...@@ -86,8 +88,8 @@ address_destroy (address_t address)
86 current = address->next; 88 current = address->next;
87 free (address); 89 free (address);
88 } 90 }
91 *paddress = NULL;
89 } 92 }
90 return 0;
91 } 93 }
92 94
93 int 95 int
......
...@@ -20,45 +20,33 @@ ...@@ -20,45 +20,33 @@
20 20
21 #include <sys/types.h> 21 #include <sys/types.h>
22 #include <stdlib.h> 22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #ifdef HAVE_STRINGS_H
27 # include <strings.h>
28 #endif
29 23
30 #include <mailutils/error.h> 24 #include <mailutils/error.h>
31 #include <mailutils/sys/attribute.h> 25 #include <mailutils/sys/attribute.h>
32 26
33 int 27 int
34 (attribute_add_ref) (attribute_t attribute) 28 attribute_ref (attribute_t attribute)
35 { 29 {
36 if (attribute == NULL || attribute->vtable == NULL 30 if (attribute == NULL || attribute->vtable == NULL
37 || attribute->vtable->add_ref == NULL) 31 || attribute->vtable->ref == NULL)
38 return MU_ERROR_NOT_SUPPORTED; 32 return MU_ERROR_NOT_SUPPORTED;
39 return attribute->vtable->add_ref (attribute); 33 return attribute->vtable->ref (attribute);
40 } 34 }
41 35
42 int 36 void
43 (attribute_release) (attribute_t attribute) 37 attribute_destroy (attribute_t *pattribute)
44 { 38 {
45 if (attribute == NULL || attribute->vtable == NULL 39 if (pattribute && *pattribute)
46 || attribute->vtable->release == NULL) 40 {
47 return MU_ERROR_NOT_SUPPORTED; 41 attribute_t attribute = *pattribute;
48 return attribute->vtable->release (attribute); 42 if (attribute->vtable && attribute->vtable->destroy)
49 } 43 attribute->vtable->destroy (pattribute);
50 44 *pattribute = NULL;
51 int 45 }
52 (attribute_destroy) (attribute_t attribute)
53 {
54 if (attribute == NULL || attribute->vtable == NULL
55 || attribute->vtable->destroy == NULL)
56 return MU_ERROR_NOT_SUPPORTED;
57 return attribute->vtable->destroy (attribute);
58 } 46 }
59 47
60 int 48 int
61 (attribute_get_flags) (attribute_t attribute, int *pflags) 49 attribute_get_flags (attribute_t attribute, int *pflags)
62 { 50 {
63 if (attribute == NULL || attribute->vtable == NULL 51 if (attribute == NULL || attribute->vtable == NULL
64 || attribute->vtable->get_flags == NULL) 52 || attribute->vtable->get_flags == NULL)
...@@ -67,7 +55,7 @@ int ...@@ -67,7 +55,7 @@ int
67 } 55 }
68 56
69 int 57 int
70 (attribute_set_flags) (attribute_t attribute, int flags) 58 attribute_set_flags (attribute_t attribute, int flags)
71 { 59 {
72 if (attribute == NULL || attribute->vtable == NULL 60 if (attribute == NULL || attribute->vtable == NULL
73 || attribute->vtable->set_flags == NULL) 61 || attribute->vtable->set_flags == NULL)
...@@ -76,7 +64,7 @@ int ...@@ -76,7 +64,7 @@ int
76 } 64 }
77 65
78 int 66 int
79 (attribute_unset_flags) (attribute_t attribute, int flags) 67 attribute_unset_flags (attribute_t attribute, int flags)
80 { 68 {
81 if (attribute == NULL || attribute->vtable == NULL 69 if (attribute == NULL || attribute->vtable == NULL
82 || attribute->vtable->unset_flags == NULL) 70 || attribute->vtable->unset_flags == NULL)
...@@ -85,7 +73,7 @@ int ...@@ -85,7 +73,7 @@ int
85 } 73 }
86 74
87 int 75 int
88 (attribute_clear_flags) (attribute_t attribute) 76 attribute_clear_flags (attribute_t attribute)
89 { 77 {
90 if (attribute == NULL || attribute->vtable == NULL 78 if (attribute == NULL || attribute->vtable == NULL
91 || attribute->vtable->clear_flags == NULL) 79 || attribute->vtable->clear_flags == NULL)
...@@ -330,114 +318,3 @@ attribute_copy (attribute_t dest, attribute_t src) ...@@ -330,114 +318,3 @@ attribute_copy (attribute_t dest, attribute_t src)
330 attribute_set_flags (dest, sflags); 318 attribute_set_flags (dest, sflags);
331 return 0; 319 return 0;
332 } 320 }
333
334 static int
335 _da_add_ref (attribute_t attribute)
336 {
337 struct _da *da = (struct _da *)attribute;
338 int status;
339 monitor_lock (da->lock);
340 status = ++da->ref;
341 monitor_unlock (da->lock);
342 return status;
343 }
344
345 static int
346 _da_destroy (attribute_t attribute)
347 {
348 struct _da *da = (struct _da *)attribute;
349 monitor_destroy (da->lock);
350 free (da);
351 return 0;
352 }
353
354 static int
355 _da_release (attribute_t attribute)
356 {
357 struct _da *da = (struct _da *)attribute;
358 int status;
359 monitor_lock (da->lock);
360 status = --da->ref;
361 if (status <= 0)
362 {
363 monitor_unlock (da->lock);
364 _da_destroy (attribute);
365 return 0;
366 }
367 monitor_unlock (da->lock);
368 return status;
369 }
370
371 static int
372 _da_get_flags (attribute_t attribute, int *pflags)
373 {
374 struct _da *da = (struct _da *)attribute;
375 monitor_lock (da->lock);
376 if (pflags)
377 *pflags = da->flags;
378 monitor_unlock (da->lock);
379 return 0;
380 }
381
382 static int
383 _da_set_flags (attribute_t attribute, int flags)
384 {
385 struct _da *da = (struct _da *)attribute;
386 monitor_lock (da->lock);
387 da->flags |= (flags | MU_ATTRIBUTE_MODIFIED);
388 monitor_unlock (da->lock);
389 return 0;
390 }
391
392 static int
393 _da_unset_flags (attribute_t attribute, int flags)
394 {
395 struct _da *da = (struct _da *)attribute;
396 monitor_lock (da->lock);
397 da->flags &= ~flags;
398 /* If Modified was being unset do not reset it. */
399 if (!(flags & MU_ATTRIBUTE_MODIFIED))
400 da->flags |= MU_ATTRIBUTE_MODIFIED;
401 monitor_unlock (da->lock);
402 return 0;
403 }
404
405 static int
406 _da_clear_flags (attribute_t attribute)
407 {
408 struct _da *da = (struct _da *)attribute;
409 monitor_lock (da->lock);
410 da->flags = 0;
411 monitor_unlock (da->lock);
412 return 0;
413 }
414
415 static struct _attribute_vtable _da_vtable =
416 {
417 _da_add_ref,
418 _da_release,
419 _da_destroy,
420
421 _da_get_flags,
422 _da_set_flags,
423 _da_unset_flags,
424 _da_clear_flags
425 };
426
427 int
428 attribute_create (attribute_t *pattribute)
429 {
430 struct _da *da;
431 if (pattribute == NULL)
432 return MU_ERROR_INVALID_PARAMETER;
433 da = calloc (1, sizeof *da);
434 if (da == NULL)
435 return MU_ERROR_NO_MEMORY;
436
437 da->base.vtable = &_da_vtable;
438 da->ref = 1;
439 da->flags = 0;
440 monitor_create (&(da->lock));
441 *pattribute = &da->base;
442 return 0;
443 }
......
...@@ -23,30 +23,24 @@ ...@@ -23,30 +23,24 @@
23 #include <mailutils/sys/authority.h> 23 #include <mailutils/sys/authority.h>
24 24
25 int 25 int
26 authority_add_ref (authority_t authority) 26 authority_ref (authority_t authority)
27 { 27 {
28 if (authority == NULL || authority->vtable == NULL 28 if (authority == NULL || authority->vtable == NULL
29 || authority->vtable->add_ref == NULL) 29 || authority->vtable->ref == NULL)
30 return MU_ERROR_NOT_SUPPORTED; 30 return MU_ERROR_NOT_SUPPORTED;
31 return authority->vtable->add_ref (authority); 31 return authority->vtable->ref (authority);
32 } 32 }
33 33
34 int 34 void
35 authority_release (authority_t authority) 35 authority_destroy (authority_t *pauthority)
36 { 36 {
37 if (authority == NULL || authority->vtable == NULL 37 if (pauthority && *pauthority)
38 || authority->vtable->release == NULL) 38 {
39 return MU_ERROR_NOT_SUPPORTED; 39 authority_t authority = *pauthority;
40 return authority->vtable->release (authority); 40 if (authority->vtable && authority->vtable->destroy)
41 } 41 authority->vtable->destroy (pauthority);
42 42 *pauthority = NULL;
43 int 43 }
44 authority_destroy (authority_t authority)
45 {
46 if (authority == NULL || authority->vtable == NULL
47 || authority->vtable->destroy == NULL)
48 return MU_ERROR_NOT_SUPPORTED;
49 return authority->vtable->destroy (authority);
50 } 44 }
51 45
52 int 46 int
......
...@@ -40,7 +40,7 @@ static void ...@@ -40,7 +40,7 @@ static void
40 _bs_cleanup (void *arg) 40 _bs_cleanup (void *arg)
41 { 41 {
42 struct _bs *bs = arg; 42 struct _bs *bs = arg;
43 monitor_unlock (bs->lock); 43 mu_refcount_unlock (bs->refcount);
44 } 44 }
45 45
46 static int 46 static int
...@@ -61,33 +61,22 @@ refill (struct _bs *bs) ...@@ -61,33 +61,22 @@ refill (struct _bs *bs)
61 } 61 }
62 62
63 static int 63 static int
64 _bs_add_ref (stream_t stream) 64 _bs_ref (stream_t stream)
65 { 65 {
66 struct _bs *bs = (struct _bs *)stream; 66 struct _bs *bs = (struct _bs *)stream;
67 return stream_add_ref (bs->stream); 67 return mu_refcount_inc (bs->refcount);
68 } 68 }
69 69
70 static int 70 static void
71 _bs_destroy (stream_t stream) 71 _bs_destroy (stream_t *pstream)
72 {
73 struct _bs *bs = (struct _bs *)stream;
74 stream_destroy (bs->stream);
75 monitor_destroy (bs->lock);
76 free (bs);
77 return 0;
78 }
79
80 static int
81 _bs_release (stream_t stream)
82 { 72 {
83 struct _bs *bs = (struct _bs *)stream; 73 struct _bs *bs = (struct _bs *)*pstream;
84 int status = stream_release (bs->stream); 74 if (mu_refcount_dec (bs->refcount) == 0)
85 if (status == 0)
86 { 75 {
87 _bs_destroy (stream); 76 stream_destroy (&bs->stream);
88 return 0; 77 mu_refcount_destroy (&bs->refcount);
78 free (bs);
89 } 79 }
90 return status;
91 } 80 }
92 81
93 static int 82 static int
...@@ -101,7 +90,7 @@ static int ...@@ -101,7 +90,7 @@ static int
101 _bs_close (stream_t stream) 90 _bs_close (stream_t stream)
102 { 91 {
103 struct _bs *bs = (struct _bs *)stream; 92 struct _bs *bs = (struct _bs *)stream;
104 monitor_lock (bs->lock); 93 mu_refcount_lock (bs->refcount);
105 /* Clear the buffer of any residue left. */ 94 /* Clear the buffer of any residue left. */
106 if (bs->rbuffer.base && bs->rbuffer.bufsize) 95 if (bs->rbuffer.base && bs->rbuffer.bufsize)
107 { 96 {
...@@ -109,7 +98,7 @@ _bs_close (stream_t stream) ...@@ -109,7 +98,7 @@ _bs_close (stream_t stream)
109 bs->rbuffer.count = 0; 98 bs->rbuffer.count = 0;
110 memset (bs->rbuffer.base, '\0', bs->rbuffer.bufsize); 99 memset (bs->rbuffer.base, '\0', bs->rbuffer.bufsize);
111 } 100 }
112 monitor_unlock (bs->lock); 101 mu_refcount_unlock (bs->refcount);
113 return stream_close (bs->stream); 102 return stream_close (bs->stream);
114 } 103 }
115 104
...@@ -141,7 +130,7 @@ _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread) ...@@ -141,7 +130,7 @@ _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
141 char *p = buf; 130 char *p = buf;
142 int r; 131 int r;
143 132
144 monitor_lock (bs->lock); 133 mu_refcount_lock (bs->refcount);
145 monitor_cleanup_push (_bs_cleanup, bs); 134 monitor_cleanup_push (_bs_cleanup, bs);
146 135
147 /* If the amount requested is bigger then the buffer cache size 136 /* If the amount requested is bigger then the buffer cache size
...@@ -200,7 +189,7 @@ _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread) ...@@ -200,7 +189,7 @@ _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
200 *pnread = count; 189 *pnread = count;
201 } 190 }
202 } 191 }
203 monitor_unlock (bs->lock); 192 mu_refcount_unlock (bs->refcount);
204 monitor_cleanup_pop (0); 193 monitor_cleanup_pop (0);
205 } 194 }
206 return status; 195 return status;
...@@ -234,7 +223,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -234,7 +223,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
234 size_t len; 223 size_t len;
235 size_t total = 0; 224 size_t total = 0;
236 225
237 monitor_lock (bs->lock); 226 mu_refcount_lock (bs->refcount);
238 monitor_cleanup_push (_bs_cleanup, bs); 227 monitor_cleanup_push (_bs_cleanup, bs);
239 228
240 count--; /* Leave space for the null. */ 229 count--; /* Leave space for the null. */
...@@ -282,7 +271,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -282,7 +271,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
282 if (pnread) 271 if (pnread)
283 *pnread = s - buf; 272 *pnread = s - buf;
284 273
285 monitor_unlock (bs->lock); 274 mu_refcount_unlock (bs->refcount);
286 monitor_cleanup_pop (0); 275 monitor_cleanup_pop (0);
287 } 276 }
288 return status; 277 return status;
...@@ -374,8 +363,13 @@ _bs_is_readready (stream_t stream, int timeout) ...@@ -374,8 +363,13 @@ _bs_is_readready (stream_t stream, int timeout)
374 { 363 {
375 struct _bs *bs = (struct _bs *)stream; 364 struct _bs *bs = (struct _bs *)stream;
376 /* Drain our buffer first. */ 365 /* Drain our buffer first. */
366 mu_refcount_lock (bs->refcount);
377 if (bs->rbuffer.count > 0) 367 if (bs->rbuffer.count > 0)
368 {
369 mu_refcount_unlock (bs->refcount);
378 return 1; 370 return 1;
371 }
372 mu_refcount_unlock (bs->refcount);
379 return stream_is_readready (bs->stream, timeout); 373 return stream_is_readready (bs->stream, timeout);
380 } 374 }
381 375
...@@ -403,8 +397,7 @@ _bs_is_open (stream_t stream) ...@@ -403,8 +397,7 @@ _bs_is_open (stream_t stream)
403 397
404 static struct _stream_vtable _bs_vtable = 398 static struct _stream_vtable _bs_vtable =
405 { 399 {
406 _bs_add_ref, 400 _bs_ref,
407 _bs_release,
408 _bs_destroy, 401 _bs_destroy,
409 402
410 _bs_open, 403 _bs_open,
...@@ -444,11 +437,16 @@ stream_buffer_create (stream_t *pstream, stream_t stream, size_t bufsize) ...@@ -444,11 +437,16 @@ stream_buffer_create (stream_t *pstream, stream_t stream, size_t bufsize)
444 if (bs == NULL) 437 if (bs == NULL)
445 return MU_ERROR_NO_MEMORY; 438 return MU_ERROR_NO_MEMORY;
446 439
447 bs->base.vtable = &_bs_vtable; 440 mu_refcount_create (&(bs->refcount));
448 bs->ref = 1; 441 if (bs->refcount == NULL)
442 {
443 free (bs);
444 return MU_ERROR_NO_MEMORY;
445 }
446
449 bs->stream = stream; 447 bs->stream = stream;
450 bs->rbuffer.bufsize = bufsize; 448 bs->rbuffer.bufsize = bufsize;
451 monitor_create (&(bs->lock)); 449 bs->base.vtable = &_bs_vtable;
452 *pstream = &bs->base; 450 *pstream = &bs->base;
453 return 0; 451 return 0;
454 } 452 }
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 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 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20
21 #include <sys/types.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #ifdef HAVE_STRINGS_H
27 # include <strings.h>
28 #endif
29
30 #include <mailutils/error.h>
31 #include <mailutils/sys/attribute.h>
32
33 static int
34 _da_ref (attribute_t attribute)
35 {
36 struct _da *da = (struct _da *)attribute;
37 return mu_refcount_inc (da->refcount);
38 }
39
40 static void
41 _da_destroy (attribute_t *pattribute)
42 {
43 struct _da *da = (struct _da *)*pattribute;
44 if (mu_refcount_dec (da->refcount) == 0)
45 {
46 mu_refcount_destroy (&da->refcount);
47 free (da);
48 }
49 }
50
51 static int
52 _da_get_flags (attribute_t attribute, int *pflags)
53 {
54 struct _da *da = (struct _da *)attribute;
55 mu_refcount_lock (da->refcount);
56 if (pflags)
57 *pflags = da->flags;
58 mu_refcount_unlock (da->refcount);
59 return 0;
60 }
61
62 static int
63 _da_set_flags (attribute_t attribute, int flags)
64 {
65 struct _da *da = (struct _da *)attribute;
66 mu_refcount_lock (da->refcount);
67 da->flags |= (flags | MU_ATTRIBUTE_MODIFIED);
68 mu_refcount_unlock (da->refcount);
69 return 0;
70 }
71
72 static int
73 _da_unset_flags (attribute_t attribute, int flags)
74 {
75 struct _da *da = (struct _da *)attribute;
76 mu_refcount_lock (da->refcount);
77 da->flags &= ~flags;
78 /* If Modified was being unset do not reset it. */
79 if (!(flags & MU_ATTRIBUTE_MODIFIED))
80 da->flags |= MU_ATTRIBUTE_MODIFIED;
81 mu_refcount_unlock (da->refcount);
82 return 0;
83 }
84
85 static int
86 _da_clear_flags (attribute_t attribute)
87 {
88 struct _da *da = (struct _da *)attribute;
89 mu_refcount_lock (da->refcount);
90 da->flags = 0;
91 mu_refcount_unlock (da->refcount);
92 return 0;
93 }
94
95 static struct _attribute_vtable _da_vtable =
96 {
97 _da_ref,
98 _da_destroy,
99
100 _da_get_flags,
101 _da_set_flags,
102 _da_unset_flags,
103 _da_clear_flags
104 };
105
106 int
107 attribute_create (attribute_t *pattribute)
108 {
109 struct _da *da;
110 if (pattribute == NULL)
111 return MU_ERROR_INVALID_PARAMETER;
112 da = calloc (1, sizeof *da);
113 if (da == NULL)
114 return MU_ERROR_NO_MEMORY;
115
116 mu_refcount_create (&(da->refcount));
117 if (da->refcount == NULL)
118 {
119 free (da);
120 return MU_ERROR_NO_MEMORY;
121 }
122 da->flags = 0;
123 da->base.vtable = &_da_vtable;
124 *pattribute = &da->base;
125 return 0;
126 }
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
34 34
35 #include <mailutils/error.h> 35 #include <mailutils/error.h>
36 #include <mailutils/sys/locker.h> 36 #include <mailutils/sys/locker.h>
37 #include <mailutils/monitor.h> 37 #include <mailutils/refcount.h>
38 38
39 /* locking flags */ 39 /* locking flags */
40 #define MU_DOTLOCK_PID 1 40 #define MU_DOTLOCK_PID 1
...@@ -50,50 +50,30 @@ ...@@ -50,50 +50,30 @@
50 struct _dotlock 50 struct _dotlock
51 { 51 {
52 struct _locker base; 52 struct _locker base;
53 monitor_t lock; 53 mu_refcount_t refcount;
54 int fd; 54 int fd;
55 int ref;
56 int refcnt; 55 int refcnt;
57 char *fname; 56 char *fname;
58 int flags; 57 int flags;
59 }; 58 };
60 59
61 static int 60 static int
62 _dotlock_add_ref (locker_t locker) 61 _dotlock_ref (locker_t locker)
63 { 62 {
64 int status;
65 struct _dotlock *dotlock = (struct _dotlock *)locker; 63 struct _dotlock *dotlock = (struct _dotlock *)locker;
66 monitor_lock (dotlock->lock); 64 return mu_refcount_inc (dotlock->refcount);
67 status = ++dotlock->ref;
68 monitor_unlock (dotlock->lock);
69 return status;
70 } 65 }
71 66
72 static int 67 static void
73 _dotlock_destroy (locker_t locker) 68 _dotlock_destroy (locker_t *plocker)
74 { 69 {
75 struct _dotlock *dotlock = (struct _dotlock *)locker; 70 struct _dotlock *dotlock = (struct _dotlock *)*plocker;
71 if (mu_refcount_dec (dotlock->refcount) == 0)
72 {
73 mu_refcount_destroy (&dotlock->refcount);
76 free (dotlock->fname); 74 free (dotlock->fname);
77 monitor_destroy (dotlock->lock);
78 free (dotlock); 75 free (dotlock);
79 return 0;
80 }
81
82 static int
83 _dotlock_release (locker_t locker)
84 {
85 int status;
86 struct _dotlock *dotlock = (struct _dotlock *)locker;
87 monitor_lock (dotlock->lock);
88 status = --dotlock->ref;
89 if (status <= 0)
90 {
91 monitor_unlock (dotlock->lock);
92 _dotlock_destroy (locker);
93 return 0;
94 } 76 }
95 monitor_unlock (dotlock->lock);
96 return status;
97 } 77 }
98 78
99 static int 79 static int
...@@ -243,8 +223,7 @@ _dotlock_unlock (locker_t locker) ...@@ -243,8 +223,7 @@ _dotlock_unlock (locker_t locker)
243 223
244 static struct _locker_vtable _dotlock_vtable = 224 static struct _locker_vtable _dotlock_vtable =
245 { 225 {
246 _dotlock_add_ref, 226 _dotlock_ref,
247 _dotlock_release,
248 _dotlock_destroy, 227 _dotlock_destroy,
249 228
250 _dotlock_lock, 229 _dotlock_lock,
...@@ -264,6 +243,13 @@ locker_dotlock_create (locker_t *plocker, const char *filename) ...@@ -264,6 +243,13 @@ locker_dotlock_create (locker_t *plocker, const char *filename)
264 if (dotlock == NULL) 243 if (dotlock == NULL)
265 return MU_ERROR_NO_MEMORY; 244 return MU_ERROR_NO_MEMORY;
266 245
246 mu_refcount_create (&dotlock->refcount);
247 if (dotlock->refcount)
248 {
249 free (dotlock);
250 return MU_ERROR_NO_MEMORY;
251 }
252
267 dotlock->fname = calloc (strlen (filename) + 5 /*strlen(".lock")*/ + 1, 1); 253 dotlock->fname = calloc (strlen (filename) + 5 /*strlen(".lock")*/ + 1, 1);
268 if (dotlock->fname == NULL) 254 if (dotlock->fname == NULL)
269 { 255 {
...@@ -273,11 +259,10 @@ locker_dotlock_create (locker_t *plocker, const char *filename) ...@@ -273,11 +259,10 @@ locker_dotlock_create (locker_t *plocker, const char *filename)
273 strcpy (dotlock->fname, filename); 259 strcpy (dotlock->fname, filename);
274 strcat (dotlock->fname, ".lock"); 260 strcat (dotlock->fname, ".lock");
275 261
276 dotlock->base.vtable = &_dotlock_vtable;
277 dotlock->flags = MU_DOTLOCK_PID | MU_DOTLOCK_TIME | MU_DOTLOCK_FCNTL; 262 dotlock->flags = MU_DOTLOCK_PID | MU_DOTLOCK_TIME | MU_DOTLOCK_FCNTL;
278 dotlock->fd = -1; 263 dotlock->fd = -1;
279 dotlock->ref = 1;
280 dotlock->refcnt = 0; 264 dotlock->refcnt = 0;
265 dotlock->base.vtable = &_dotlock_vtable;
281 *plocker = &dotlock->base; 266 *plocker = &dotlock->base;
282 return 0; 267 return 0;
283 } 268 }
......
...@@ -23,55 +23,76 @@ ...@@ -23,55 +23,76 @@
23 #include <mailutils/sys/envelope.h> 23 #include <mailutils/sys/envelope.h>
24 24
25 int 25 int
26 (envelope_add_ref) (envelope_t envelope) 26 envelope_ref (envelope_t envelope)
27 { 27 {
28 if (envelope == NULL || envelope->vtable == NULL 28 if (envelope == NULL || envelope->vtable == NULL
29 || envelope->vtable->add_ref == NULL) 29 || envelope->vtable->ref == NULL)
30 return MU_ERROR_NOT_SUPPORTED; 30 return MU_ERROR_NOT_SUPPORTED;
31 return envelope->vtable->add_ref (envelope); 31 return envelope->vtable->ref (envelope);
32 }
33
34 void
35 envelope_destroy (envelope_t *penvelope)
36 {
37 if (penvelope && *penvelope)
38 {
39 envelope_t envelope = *penvelope;
40 if (envelope->vtable && envelope->vtable->destroy)
41 envelope->vtable->destroy (penvelope);
42 *penvelope = NULL;
43 }
44 }
45
46 int
47 envelope_get_sender (envelope_t envelope, address_t *paddr)
48 {
49 if (envelope == NULL || envelope->vtable == NULL
50 || envelope->vtable->get_sender == NULL)
51 return MU_ERROR_NOT_SUPPORTED;
52 return envelope->vtable->get_sender (envelope, paddr);
32 } 53 }
33 54
34 int 55 int
35 (envelope_release) (envelope_t envelope) 56 envelope_set_sender (envelope_t envelope, address_t addr)
36 { 57 {
37 if (envelope == NULL || envelope->vtable == NULL 58 if (envelope == NULL || envelope->vtable == NULL
38 || envelope->vtable->release == NULL) 59 || envelope->vtable->set_sender == NULL)
39 return MU_ERROR_NOT_SUPPORTED; 60 return MU_ERROR_NOT_SUPPORTED;
40 return envelope->vtable->release (envelope); 61 return envelope->vtable->set_sender (envelope, addr);
41 } 62 }
42 63
43 int 64 int
44 (envelope_destroy) (envelope_t envelope) 65 envelope_get_recipient (envelope_t envelope, address_t *paddr)
45 { 66 {
46 if (envelope == NULL || envelope->vtable == NULL 67 if (envelope == NULL || envelope->vtable == NULL
47 || envelope->vtable->destroy == NULL) 68 || envelope->vtable->get_recipient == NULL)
48 return MU_ERROR_NOT_SUPPORTED; 69 return MU_ERROR_NOT_SUPPORTED;
49 return envelope->vtable->destroy (envelope); 70 return envelope->vtable->get_recipient (envelope, paddr);
50 } 71 }
51 72
52 int 73 int
53 (envelope_sender) (envelope_t envelope, address_t *paddr) 74 envelope_set_recipient (envelope_t envelope, address_t addr)
54 { 75 {
55 if (envelope == NULL || envelope->vtable == NULL 76 if (envelope == NULL || envelope->vtable == NULL
56 || envelope->vtable->sender == NULL) 77 || envelope->vtable->set_recipient == NULL)
57 return MU_ERROR_NOT_SUPPORTED; 78 return MU_ERROR_NOT_SUPPORTED;
58 return envelope->vtable->sender (envelope, paddr); 79 return envelope->vtable->set_recipient (envelope, addr);
59 } 80 }
60 81
61 int 82 int
62 (envelope_recipient) (envelope_t envelope, address_t *paddr) 83 envelope_get_date (envelope_t envelope, struct tm *tm, struct mu_timezone *tz)
63 { 84 {
64 if (envelope == NULL || envelope->vtable == NULL 85 if (envelope == NULL || envelope->vtable == NULL
65 || envelope->vtable->recipient == NULL) 86 || envelope->vtable->get_date == NULL)
66 return MU_ERROR_NOT_SUPPORTED; 87 return MU_ERROR_NOT_SUPPORTED;
67 return envelope->vtable->recipient (envelope, paddr); 88 return envelope->vtable->get_date (envelope, tm, tz);
68 } 89 }
69 90
70 int 91 int
71 (envelope_date) (envelope_t envelope, struct tm *tm, struct mu_timezone *tz) 92 envelope_set_date (envelope_t envelope, struct tm *tm, struct mu_timezone *tz)
72 { 93 {
73 if (envelope == NULL || envelope->vtable == NULL 94 if (envelope == NULL || envelope->vtable == NULL
74 || envelope->vtable->date == NULL) 95 || envelope->vtable->set_date == NULL)
75 return MU_ERROR_NOT_SUPPORTED; 96 return MU_ERROR_NOT_SUPPORTED;
76 return envelope->vtable->date (envelope, tm, tz); 97 return envelope->vtable->set_date (envelope, tm, tz);
77 } 98 }
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 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 Library General 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 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 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30
31 #include <mailutils/sys/fdstream.h>
32 #include <mailutils/monitor.h>
33 #include <mailutils/error.h>
34
35 static void
36 _fds_cleanup (void *arg)
37 {
38 struct _fds *fds = arg;
39 mu_refcount_unlock (fds->refcount);
40 }
41
42 static int
43 _fds_ref (stream_t stream)
44 {
45 struct _fds *fds = (struct _fds *)stream;
46 return mu_refcount_inc (fds->refcount);
47 }
48
49 static void
50 _fds_destroy (stream_t *pstream)
51 {
52 struct _fds *fds = (struct _fds *)*pstream;
53 if (mu_refcount_dec (fds->refcount) == 0)
54 {
55 if (fds->fd != -1)
56 close (fds->fd);
57 mu_refcount_destroy (&fds->refcount);
58 free (fds);
59 }
60 }
61
62 static int
63 _fds_close0 (stream_t stream)
64 {
65 struct _fds *fds = (struct _fds *)stream;
66 if (fds->fd != -1)
67 close (fds->fd);
68 fds->fd = -1;
69 return 0;
70 }
71
72 static int
73 _fds_close (stream_t stream)
74 {
75 struct _fds *fds = (struct _fds *)stream;
76
77 mu_refcount_lock (fds->refcount);
78 monitor_cleanup_push (_fds_cleanup, fds);
79 _fds_close0 (stream);
80 mu_refcount_unlock (fds->refcount);
81 monitor_cleanup_pop (0);
82 return 0;
83 }
84
85 static int
86 _fds_open (stream_t stream, const char *name, int port, int flags)
87 {
88 (void)stream; (void)name; (void)port; (void)flags;
89 return MU_ERROR_NOT_SUPPORTED;
90 }
91
92 static int
93 _fds_get_fd (stream_t stream, int *fd)
94 {
95 struct _fds *fds = (struct _fds *)stream;
96
97 if (fd == NULL || fds->fd == -1)
98 return MU_ERROR_INVALID_PARAMETER;
99
100 *fd = fds->fd;
101 return 0;
102 }
103
104 static int
105 _fds_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
106 {
107 struct _fds *fds = (struct _fds *)stream;
108 int bytes = 0;
109 int status = 0;
110
111 bytes = read (fds->fd, buf, buf_size);
112 if (bytes == -1)
113 {
114 bytes = 0;
115 status = errno;
116 }
117 if (br)
118 *br = bytes;
119 return status;
120 }
121
122 static int
123 _fds_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
124 {
125 struct _fds *fds = (struct _fds *)stream;
126 int status = 0;
127 size_t n;
128 int nr = 0;
129 char c;
130
131 /* Grossly inefficient hopefully they override this */
132 for (n = 1; n < buf_size; n++)
133 {
134 nr = read (fds->fd, &c, 1);
135 if (nr == -1) /* Error. */
136 {
137 status = errno;
138 break;
139 }
140 else if (nr == 1)
141 {
142 *buf++ = c;
143 if (c == '\n') /* Newline is stored like fgets(). */
144 break;
145 }
146 else if (nr == 0)
147 {
148 if (n == 1) /* EOF, no data read. */
149 n = 0;
150 break; /* EOF, some data was read. */
151 }
152 }
153 *buf = '\0';
154 if (br)
155 *br = (n == buf_size) ? n - 1: n;
156 return status;
157 }
158
159 static int
160 _fds_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
161 {
162 struct _fds *fds = (struct _fds *)stream;
163 int bytes = 0;
164 int status = 0;
165
166 bytes = write (fds->fd, buf, buf_size);
167 if (bytes == -1)
168 {
169 bytes = 0;
170 status = errno;
171 }
172 if (bw)
173 *bw = bytes;
174 return status;
175 }
176
177 static int
178 _fds_seek (stream_t stream, off_t off, enum stream_whence whence)
179 {
180 struct _fds *fds = (struct _fds *)stream;
181 int err = 0;
182 if (fds->fd)
183 {
184 if (whence == MU_STREAM_WHENCE_SET)
185 off = lseek (fds->fd, off, SEEK_SET);
186 else if (whence == MU_STREAM_WHENCE_CUR)
187 off = lseek (fds->fd, off, SEEK_CUR);
188 else if (whence == MU_STREAM_WHENCE_END)
189 off = lseek (fds->fd, off, SEEK_END);
190 else
191 err = MU_ERROR_INVALID_PARAMETER;
192 if (err == -1)
193 err = errno;
194 }
195 return err;
196 }
197
198 static int
199 _fds_tell (stream_t stream, off_t *off)
200 {
201 struct _fds *fds = (struct _fds *)stream;
202 int err = 0;
203 if (off)
204 {
205 *off = lseek (fds->fd, 0, SEEK_CUR);
206 if (*off == -1)
207 {
208 err = errno;
209 *off = 0;
210 }
211 }
212 return err;;
213 }
214
215 static int
216 _fds_get_size (stream_t stream, off_t *psize)
217 {
218 struct _fds *fds = (struct _fds *)stream;
219 struct stat stbuf;
220 int err = 0;
221 stbuf.st_size = 0;
222 if (fstat (fds->fd, &stbuf) == -1)
223 err = errno;
224 if (psize)
225 *psize = stbuf.st_size;
226 return err;
227 }
228
229 static int
230 _fds_truncate (stream_t stream, off_t len)
231 {
232 struct _fds *fds = (struct _fds *)stream;
233 int err = 0;
234 if (ftruncate (fds->fd, len) == -1)
235 err = errno ;
236 return err;
237 }
238
239 static int
240 _fds_flush (stream_t stream)
241 {
242 (void)stream;
243 return 0;
244 }
245
246 static int
247 _fds_get_flags (stream_t stream, int *flags)
248 {
249 struct _fds *fds = (struct _fds *)stream;
250 if (flags == NULL)
251 return MU_ERROR_INVALID_PARAMETER;
252 *flags = fds->flags;
253 return 0;
254 }
255
256 static int
257 _fds_get_state (stream_t stream, enum stream_state *state)
258 {
259 (void)stream;
260 if (state == NULL)
261 return MU_ERROR_INVALID_PARAMETER;
262 *state = MU_STREAM_NO_STATE;
263 return 0;
264 }
265
266 static int
267 _fds_is_readready (stream_t stream, int timeout)
268 {
269 struct _fds *fds = (struct _fds *)stream;
270 int ready;
271 struct timeval tv;
272 fd_set fset;
273
274 FD_ZERO (&fset);
275 FD_SET (fds->fd, &fset);
276
277 tv.tv_sec = timeout / 100;
278 tv.tv_usec = (timeout % 1000) * 1000;
279
280 ready = select (fds->fd + 1, &fset, NULL, NULL, (timeout == -1) ? NULL: &tv);
281 return (ready == -1) ? 0 : 1;
282 }
283
284 static int
285 _fds_is_writeready (stream_t stream, int timeout)
286 {
287 struct _fds *fds = (struct _fds *)stream;
288 int ready;
289 struct timeval tv;
290 fd_set fset;
291
292 FD_ZERO (&fset);
293 FD_SET (fds->fd, &fset);
294
295 tv.tv_sec = timeout / 100;
296 tv.tv_usec = (timeout % 1000) * 1000;
297
298 ready = select (fds->fd + 1, NULL, &fset, NULL, (timeout == -1) ? NULL: &tv);
299 return (ready == -1) ? 0 : 1;
300 }
301
302 static int
303 _fds_is_exceptionpending (stream_t stream, int timeout)
304 {
305 struct _fds *fds = (struct _fds *)stream;
306 int ready;
307 struct timeval tv;
308 fd_set fset;
309
310 FD_ZERO (&fset);
311 FD_SET (fds->fd, &fset);
312
313 tv.tv_sec = timeout / 100;
314 tv.tv_usec = (timeout % 1000) * 1000;
315
316 ready = select (fds->fd + 1, NULL, NULL, &fset, (timeout == -1) ? NULL: &tv);
317 return (ready == -1) ? 0 : 1;
318 }
319
320 static int
321 _fds_is_open (stream_t stream)
322 {
323 struct _fds *fds = (struct _fds *)stream;
324 return fds->fd >= 0;
325 }
326
327 static struct _stream_vtable _fds_vtable =
328 {
329 _fds_ref,
330 _fds_destroy,
331
332 _fds_open,
333 _fds_close,
334
335 _fds_read,
336 _fds_readline,
337 _fds_write,
338
339 _fds_seek,
340 _fds_tell,
341
342 _fds_get_size,
343 _fds_truncate,
344 _fds_flush,
345
346 _fds_get_fd,
347 _fds_get_flags,
348 _fds_get_state,
349
350 _fds_is_readready,
351 _fds_is_writeready,
352 _fds_is_exceptionpending,
353
354 _fds_is_open
355 };
356
357 int
358 stream_fd_create (stream_t *pstream, int fd)
359 {
360 struct _fds *fds;
361
362 if (pstream == NULL || fd < 0)
363 return MU_ERROR_INVALID_PARAMETER;
364
365 fds = calloc (1, sizeof *fds);
366 if (fds == NULL)
367 return MU_ERROR_NO_MEMORY;
368
369 mu_refcount_create (&fds->refcount);
370 if (fds->refcount == NULL)
371 {
372 free (fds);
373 return MU_ERROR_NO_MEMORY;
374 }
375 fds->fd = fd;
376 fds->base.vtable = &_fds_vtable;
377 *pstream = &fds->base;
378 return 0;
379 }
...@@ -20,30 +20,24 @@ ...@@ -20,30 +20,24 @@
20 #include <mailutils/sys/folder.h> 20 #include <mailutils/sys/folder.h>
21 21
22 int 22 int
23 folder_add_ref (folder_t folder) 23 folder_ref (folder_t folder)
24 { 24 {
25 if (folder == NULL || folder->vtable == NULL 25 if (folder == NULL || folder->vtable == NULL
26 || folder->vtable->add_ref == NULL) 26 || folder->vtable->ref == NULL)
27 return MU_ERROR_NOT_SUPPORTED; 27 return MU_ERROR_NOT_SUPPORTED;
28 return folder->vtable->add_ref (folder); 28 return folder->vtable->ref (folder);
29 } 29 }
30 30
31 int 31 void
32 folder_release (folder_t folder) 32 folder_destroy (folder_t *pfolder)
33 { 33 {
34 if (folder == NULL || folder->vtable == NULL 34 if (pfolder && *pfolder)
35 || folder->vtable->release == NULL) 35 {
36 return MU_ERROR_NOT_SUPPORTED; 36 folder_t folder = *pfolder;
37 return folder->vtable->release (folder); 37 if (folder->vtable && folder->vtable->destroy)
38 } 38 folder->vtable->destroy (pfolder);
39 39 *pfolder = NULL;
40 int 40 }
41 folder_destroy (folder_t folder)
42 {
43 if (folder == NULL || folder->vtable == NULL
44 || folder->vtable->destroy == NULL)
45 return MU_ERROR_NOT_SUPPORTED;
46 return folder->vtable->destroy (folder);
47 } 41 }
48 42
49 int 43 int
......
...@@ -35,42 +35,23 @@ ...@@ -35,42 +35,23 @@
35 35
36 36
37 static int 37 static int
38 _fs_add_ref (stream_t stream) 38 _fs_ref (stream_t stream)
39 { 39 {
40 struct _fs *fs = (struct _fs *)stream; 40 struct _fs *fs = (struct _fs *)stream;
41 int status; 41 return mu_refcount_inc (fs->refcount);
42 monitor_lock (fs->lock);
43 status = ++fs->ref;
44 monitor_unlock (fs->lock);
45 return status;
46 } 42 }
47 43
48 static int 44 static void
49 _fs_destroy (stream_t stream) 45 _fs_destroy (stream_t *pstream)
50 { 46 {
51 struct _fs *fs = (struct _fs *)stream; 47 struct _fs *fs = (struct _fs *)*pstream;
48 if (mu_refcount_dec (fs->refcount) == 0)
49 {
52 if (fs->file) 50 if (fs->file)
53 fclose (fs->file); 51 fclose (fs->file);
54 monitor_destroy (fs->lock); 52 mu_refcount_destroy (&fs->refcount);
55 free (fs); 53 free (fs);
56 return 0;
57 }
58
59 static int
60 _fs_release (stream_t stream)
61 {
62 int status;
63 struct _fs *fs = (struct _fs *)stream;
64 monitor_lock (fs->lock);
65 status = --fs->ref;
66 if (status <= 0)
67 {
68 monitor_unlock (fs->lock);
69 _fs_destroy (stream);
70 return 0;
71 } 54 }
72 monitor_unlock (fs->lock);
73 return status;
74 } 55 }
75 56
76 static int 57 static int
...@@ -201,7 +182,6 @@ _fs_seek (stream_t stream, off_t off, enum stream_whence whence) ...@@ -201,7 +182,6 @@ _fs_seek (stream_t stream, off_t off, enum stream_whence whence)
201 int err = 0; 182 int err = 0;
202 if (fs->file) 183 if (fs->file)
203 { 184 {
204 errno = MU_ERROR_INVALID_PARAMETER;
205 if (whence == MU_STREAM_WHENCE_SET) 185 if (whence == MU_STREAM_WHENCE_SET)
206 err = fseek (fs->file, off, SEEK_SET); 186 err = fseek (fs->file, off, SEEK_SET);
207 else if (whence == MU_STREAM_WHENCE_CUR) 187 else if (whence == MU_STREAM_WHENCE_CUR)
...@@ -210,7 +190,7 @@ _fs_seek (stream_t stream, off_t off, enum stream_whence whence) ...@@ -210,7 +190,7 @@ _fs_seek (stream_t stream, off_t off, enum stream_whence whence)
210 err = fseek (fs->file, off, SEEK_END); 190 err = fseek (fs->file, off, SEEK_END);
211 else 191 else
212 err = MU_ERROR_INVALID_PARAMETER; 192 err = MU_ERROR_INVALID_PARAMETER;
213 if (err != 0) 193 if (err == -1)
214 err = errno; 194 err = errno;
215 } 195 }
216 return err; 196 return err;
...@@ -395,8 +375,7 @@ _fs_open (stream_t stream, const char *filename, int port, int flags) ...@@ -395,8 +375,7 @@ _fs_open (stream_t stream, const char *filename, int port, int flags)
395 375
396 static struct _stream_vtable _fs_vtable = 376 static struct _stream_vtable _fs_vtable =
397 { 377 {
398 _fs_add_ref, 378 _fs_ref,
399 _fs_release,
400 _fs_destroy, 379 _fs_destroy,
401 380
402 _fs_open, 381 _fs_open,
...@@ -436,11 +415,40 @@ stream_file_create (stream_t *pstream) ...@@ -436,11 +415,40 @@ stream_file_create (stream_t *pstream)
436 if (fs == NULL) 415 if (fs == NULL)
437 return MU_ERROR_NO_MEMORY ; 416 return MU_ERROR_NO_MEMORY ;
438 417
439 fs->base.vtable = &_fs_vtable; 418 mu_refcount_create (&fs->refcount);
440 fs->ref = 1; 419 if (fs->refcount == NULL)
420 {
421 free (fs);
422 return MU_ERROR_NO_MEMORY ;
423 }
441 fs->file = NULL; 424 fs->file = NULL;
442 fs->flags = 0; 425 fs->flags = 0;
443 monitor_create (&(fs->lock)); 426 fs->base.vtable = &_fs_vtable;
427 *pstream = &fs->base;
428 return 0;
429 }
430
431 int
432 stream_stdio_create (stream_t *pstream, FILE *fp)
433 {
434 struct _fs *fs;
435
436 if (pstream == NULL)
437 return MU_ERROR_INVALID_PARAMETER;
438
439 fs = calloc (1, sizeof *fs);
440 if (fs == NULL)
441 return MU_ERROR_NO_MEMORY ;
442
443 mu_refcount_create (&fs->refcount);
444 if (fs->refcount == NULL)
445 {
446 free (fs);
447 return MU_ERROR_NO_MEMORY ;
448 }
449 fs->file = fp;
450 fs->flags = 0;
451 fs->base.vtable = &_fs_vtable;
444 *pstream = &fs->base; 452 *pstream = &fs->base;
445 return 0; 453 return 0;
446 } 454 }
......
...@@ -26,34 +26,28 @@ ...@@ -26,34 +26,28 @@
26 #include <mailutils/sys/header.h> 26 #include <mailutils/sys/header.h>
27 27
28 int 28 int
29 (header_add_ref) (header_t header) 29 header_ref (header_t header)
30 { 30 {
31 if (header == NULL || header->vtable == NULL 31 if (header == NULL || header->vtable == NULL
32 || header->vtable->add_ref == NULL) 32 || header->vtable->ref == NULL)
33 return MU_ERROR_NOT_SUPPORTED; 33 return MU_ERROR_NOT_SUPPORTED;
34 return header->vtable->add_ref (header); 34 return header->vtable->ref (header);
35 } 35 }
36 36
37 int 37 void
38 (header_release) (header_t header) 38 header_destroy (header_t *pheader)
39 { 39 {
40 if (header == NULL || header->vtable == NULL 40 if (pheader && *pheader)
41 || header->vtable->release == NULL) 41 {
42 return MU_ERROR_NOT_SUPPORTED; 42 header_t header = *pheader;
43 return header->vtable->release (header); 43 if (header->vtable && header->vtable->destroy)
44 } 44 header->vtable->destroy (pheader);
45 45 *pheader = NULL;
46 int 46 }
47 (header_destroy) (header_t header)
48 {
49 if (header == NULL || header->vtable == NULL
50 || header->vtable->destroy == NULL)
51 return MU_ERROR_NOT_SUPPORTED;
52 return header->vtable->destroy (header);
53 } 47 }
54 48
55 int 49 int
56 (header_is_modified) (header_t header) 50 header_is_modified (header_t header)
57 { 51 {
58 if (header == NULL || header->vtable == NULL 52 if (header == NULL || header->vtable == NULL
59 || header->vtable->is_modified == NULL) 53 || header->vtable->is_modified == NULL)
...@@ -62,7 +56,7 @@ int ...@@ -62,7 +56,7 @@ int
62 } 56 }
63 57
64 int 58 int
65 (header_clear_modified) (header_t header) 59 header_clear_modified (header_t header)
66 { 60 {
67 if (header == NULL || header->vtable == NULL 61 if (header == NULL || header->vtable == NULL
68 || header->vtable->clear_modified == NULL) 62 || header->vtable->clear_modified == NULL)
...@@ -71,8 +65,7 @@ int ...@@ -71,8 +65,7 @@ int
71 } 65 }
72 66
73 int 67 int
74 (header_set_value) (header_t header, const char *fn, const char *fv, 68 header_set_value (header_t header, const char *fn, const char *fv, int replace)
75 int replace)
76 { 69 {
77 if (header == NULL || header->vtable == NULL 70 if (header == NULL || header->vtable == NULL
78 || header->vtable->set_value == NULL) 71 || header->vtable->set_value == NULL)
...@@ -81,7 +74,7 @@ int ...@@ -81,7 +74,7 @@ int
81 } 74 }
82 75
83 int 76 int
84 (header_get_value) (header_t header, const char *name, char *buffer, 77 header_get_value (header_t header, const char *name, char *buffer,
85 size_t buflen, size_t *pn) 78 size_t buflen, size_t *pn)
86 { 79 {
87 if (header == NULL || header->vtable == NULL 80 if (header == NULL || header->vtable == NULL
...@@ -108,7 +101,7 @@ header_aget_value (header_t header, const char *name, char **pvalue) ...@@ -108,7 +101,7 @@ header_aget_value (header_t header, const char *name, char **pvalue)
108 } 101 }
109 102
110 int 103 int
111 (header_get_field_count) (header_t header, size_t *pcount) 104 header_get_field_count (header_t header, size_t *pcount)
112 { 105 {
113 if (header == NULL || header->vtable == NULL 106 if (header == NULL || header->vtable == NULL
114 || header->vtable->get_field_count == NULL) 107 || header->vtable->get_field_count == NULL)
...@@ -117,7 +110,7 @@ int ...@@ -117,7 +110,7 @@ int
117 } 110 }
118 111
119 int 112 int
120 (header_get_field_name) (header_t header, size_t num, char *buf, 113 header_get_field_name (header_t header, size_t num, char *buf,
121 size_t buflen, size_t *pn) 114 size_t buflen, size_t *pn)
122 { 115 {
123 if (header == NULL || header->vtable == NULL 116 if (header == NULL || header->vtable == NULL
...@@ -144,7 +137,7 @@ header_aget_field_name (header_t header, size_t num, char **pvalue) ...@@ -144,7 +137,7 @@ header_aget_field_name (header_t header, size_t num, char **pvalue)
144 } 137 }
145 138
146 int 139 int
147 (header_get_field_value) (header_t header, size_t num, char *buf, 140 header_get_field_value (header_t header, size_t num, char *buf,
148 size_t buflen, size_t *pn) 141 size_t buflen, size_t *pn)
149 { 142 {
150 if (header == NULL || header->vtable == NULL 143 if (header == NULL || header->vtable == NULL
...@@ -171,7 +164,7 @@ header_aget_field_value (header_t header, size_t num, char **pvalue) ...@@ -171,7 +164,7 @@ header_aget_field_value (header_t header, size_t num, char **pvalue)
171 } 164 }
172 165
173 int 166 int
174 (header_get_lines) (header_t header, size_t *plines) 167 header_get_lines (header_t header, size_t *plines)
175 { 168 {
176 if (header == NULL || header->vtable == NULL 169 if (header == NULL || header->vtable == NULL
177 || header->vtable->get_lines == NULL) 170 || header->vtable->get_lines == NULL)
...@@ -180,7 +173,7 @@ int ...@@ -180,7 +173,7 @@ int
180 } 173 }
181 174
182 int 175 int
183 (header_get_size) (header_t header, size_t *psize) 176 header_get_size (header_t header, size_t *psize)
184 { 177 {
185 if (header == NULL || header->vtable == NULL 178 if (header == NULL || header->vtable == NULL
186 || header->vtable->get_size == NULL) 179 || header->vtable->get_size == NULL)
...@@ -189,7 +182,7 @@ int ...@@ -189,7 +182,7 @@ int
189 } 182 }
190 183
191 int 184 int
192 (header_get_stream) (header_t header, stream_t *pstream) 185 header_get_stream (header_t header, stream_t *pstream)
193 { 186 {
194 if (header == NULL || header->vtable == NULL 187 if (header == NULL || header->vtable == NULL
195 || header->vtable->get_stream == NULL) 188 || header->vtable->get_stream == NULL)
......
...@@ -27,6 +27,7 @@ pkginclude_HEADERS = \ ...@@ -27,6 +27,7 @@ pkginclude_HEADERS = \
27 parse822.h \ 27 parse822.h \
28 pop3.h \ 28 pop3.h \
29 property.h \ 29 property.h \
30 refcount.h \
30 stream.h \ 31 stream.h \
31 ticket.h \ 32 ticket.h \
32 url.h 33 url.h
......
...@@ -37,9 +37,8 @@ typedef struct _address *address_t; ...@@ -37,9 +37,8 @@ typedef struct _address *address_t;
37 37
38 extern int address_create __P ((address_t *, const char *)); 38 extern int address_create __P ((address_t *, const char *));
39 39
40 extern int address_add_ref __P ((address_t)); 40 extern int address_ref __P ((address_t));
41 extern int address_release __P ((address_t)); 41 extern void address_destroy __P ((address_t *));
42 extern int address_destroy __P ((address_t));
43 42
44 extern int address_get_email 43 extern int address_get_email
45 __P ((address_t, size_t, char *, size_t, size_t *)); 44 __P ((address_t, size_t, char *, size_t, size_t *));
......
...@@ -44,9 +44,8 @@ typedef struct _attribute * attribute_t; ...@@ -44,9 +44,8 @@ typedef struct _attribute * attribute_t;
44 44
45 extern int attribute_create __P ((attribute_t *)); 45 extern int attribute_create __P ((attribute_t *));
46 46
47 extern int attribute_add_ref __P ((attribute_t)); 47 extern int attribute_ref __P ((attribute_t));
48 extern int attribute_release __P ((attribute_t)); 48 extern void attribute_destroy __P ((attribute_t *));
49 extern int attribute_destroy __P ((attribute_t));
50 49
51 extern int attribute_is_seen __P ((attribute_t)); 50 extern int attribute_is_seen __P ((attribute_t));
52 extern int attribute_is_answered __P ((attribute_t)); 51 extern int attribute_is_answered __P ((attribute_t));
......
...@@ -37,9 +37,8 @@ extern "C" { ...@@ -37,9 +37,8 @@ extern "C" {
37 struct _authority; 37 struct _authority;
38 typedef struct _authority *authority_t; 38 typedef struct _authority *authority_t;
39 39
40 extern int authority_add_ref __P ((authority_t)); 40 extern int authority_ref __P ((authority_t));
41 extern int authority_release __P ((authority_t)); 41 extern void authority_destroy __P ((authority_t *));
42 extern int authority_destroy __P ((authority_t));
43 extern int authority_set_ticket __P ((authority_t, ticket_t)); 42 extern int authority_set_ticket __P ((authority_t, ticket_t));
44 extern int authority_get_ticket __P ((authority_t, ticket_t *)); 43 extern int authority_get_ticket __P ((authority_t, ticket_t *));
45 extern int authority_authenticate __P ((authority_t)); 44 extern int authority_authenticate __P ((authority_t));
......
...@@ -38,8 +38,8 @@ extern "C" { ...@@ -38,8 +38,8 @@ extern "C" {
38 struct _body; 38 struct _body;
39 typedef struct _body *body_t; 39 typedef struct _body *body_t;
40 40
41 extern int body_add_ref __P ((body_t)); 41 extern int body_ref __P ((body_t));
42 extern int body_release __P ((body_t)); 42 extern void body_release __P ((body_t *));
43 extern int body_destroy __P ((body_t)); 43 extern int body_destroy __P ((body_t));
44 44
45 extern int body_is_modified __P ((body_t)); 45 extern int body_is_modified __P ((body_t));
......
...@@ -38,9 +38,8 @@ typedef struct _debug* mu_debug_t; ...@@ -38,9 +38,8 @@ typedef struct _debug* mu_debug_t;
38 38
39 #define MU_DEBUG_TRACE 1 39 #define MU_DEBUG_TRACE 1
40 #define MU_DEBUG_PROT 2 40 #define MU_DEBUG_PROT 2
41 extern int mu_debug_add_ref __P ((mu_debug_t)); 41 extern int mu_debug_ref __P ((mu_debug_t));
42 extern int mu_debug_release __P ((mu_debug_t)); 42 extern void mu_debug_destroy __P ((mu_debug_t *));
43 extern int mu_debug_destroy __P ((mu_debug_t));
44 extern int mu_debug_set_level __P ((mu_debug_t, size_t level)); 43 extern int mu_debug_set_level __P ((mu_debug_t, size_t level));
45 extern int mu_debug_get_level __P ((mu_debug_t, size_t *plevel)); 44 extern int mu_debug_get_level __P ((mu_debug_t, size_t *plevel));
46 extern int mu_debug_print __P ((mu_debug_t debug, size_t level, 45 extern int mu_debug_print __P ((mu_debug_t debug, size_t level,
......
...@@ -36,13 +36,15 @@ extern "C" { ...@@ -36,13 +36,15 @@ extern "C" {
36 struct _envelope; 36 struct _envelope;
37 typedef struct _envelope *envelope_t; 37 typedef struct _envelope *envelope_t;
38 38
39 extern int envelope_add_ref __P ((envelope_t)); 39 extern int envelope_ref __P ((envelope_t));
40 extern int envelope_release __P ((envelope_t)); 40 extern void envelope_destroy __P ((envelope_t *));
41 extern int envelope_destroy __P ((envelope_t)); 41
42 42 extern int envelope_get_sender __P ((envelope_t, address_t *));
43 extern int envelope_sender __P ((envelope_t, address_t *)); 43 extern int envelope_set_sender __P ((envelope_t, address_t));
44 extern int envelope_recipient __P ((envelope_t, address_t *)); 44 extern int envelope_get_recipient __P ((envelope_t, address_t *));
45 extern int envelope_date __P ((envelope_t, struct tm *, struct mu_timezone *)); 45 extern int envelope_set_recipient __P ((envelope_t, address_t));
46 extern int envelope_get_date __P ((envelope_t, struct tm *, struct mu_timezone *));
47 extern int envelope_set_date __P ((envelope_t, struct tm *, struct mu_timezone *));
46 48
47 #ifdef __cplusplus 49 #ifdef __cplusplus
48 } 50 }
......
...@@ -56,11 +56,10 @@ struct list_response ...@@ -56,11 +56,10 @@ struct list_response
56 56
57 extern int folder_create __P ((folder_t *, const char *)); 57 extern int folder_create __P ((folder_t *, const char *));
58 58
59 extern int folder_add_ref __P ((folder_t)); 59 extern int folder_ref __P ((folder_t));
60 extern int folder_release __P ((folder_t)); 60 extern void folder_destroy __P ((folder_t *));
61 extern int folder_destroy __P ((folder_t));
62 61
63 extern int folder_open __P ((folder_t, int flag)); 62 extern int folder_open __P ((folder_t, int));
64 extern int folder_close __P ((folder_t)); 63 extern int folder_close __P ((folder_t));
65 64
66 extern int folder_delete __P ((folder_t, const char *)); 65 extern int folder_delete __P ((folder_t, const char *));
......
...@@ -77,9 +77,8 @@ extern "C" { ...@@ -77,9 +77,8 @@ extern "C" {
77 struct _header; 77 struct _header;
78 typedef struct _header * header_t; 78 typedef struct _header * header_t;
79 79
80 extern int header_add_ref __P ((header_t)); 80 extern int header_ref __P ((header_t));
81 extern int header_release __P ((header_t)); 81 extern void header_destroy __P ((header_t *));
82 extern int header_destroy __P ((header_t));
83 82
84 extern int header_is_modified __P ((header_t)); 83 extern int header_is_modified __P ((header_t));
85 extern int header_clear_modified __P ((header_t)); 84 extern int header_clear_modified __P ((header_t));
......
...@@ -33,9 +33,8 @@ extern "C" { ...@@ -33,9 +33,8 @@ extern "C" {
33 struct _iterator; 33 struct _iterator;
34 typedef struct _iterator *iterator_t; 34 typedef struct _iterator *iterator_t;
35 35
36 extern int iterator_add_ref __P ((iterator_t)); 36 extern int iterator_ref __P ((iterator_t));
37 extern int iterator_destroy __P ((iterator_t)); 37 extern void iterator_destroy __P ((iterator_t *));
38 extern int iterator_release __P ((iterator_t));
39 38
40 extern int iterator_first __P ((iterator_t)); 39 extern int iterator_first __P ((iterator_t));
41 extern int iterator_next __P ((iterator_t)); 40 extern int iterator_next __P ((iterator_t));
......
...@@ -37,7 +37,8 @@ struct _list; ...@@ -37,7 +37,8 @@ struct _list;
37 typedef struct _list *mu_list_t; 37 typedef struct _list *mu_list_t;
38 38
39 extern int mu_list_create __P ((mu_list_t *)); 39 extern int mu_list_create __P ((mu_list_t *));
40 extern int mu_list_destroy __P ((mu_list_t)); 40 extern int mu_list_ref __P ((mu_list_t));
41 extern void mu_list_destroy __P ((mu_list_t *));
41 extern int mu_list_append __P ((mu_list_t, void *)); 42 extern int mu_list_append __P ((mu_list_t, void *));
42 extern int mu_list_prepend __P ((mu_list_t, void *)); 43 extern int mu_list_prepend __P ((mu_list_t, void *));
43 extern int mu_list_is_empty __P ((mu_list_t)); 44 extern int mu_list_is_empty __P ((mu_list_t));
......
...@@ -35,9 +35,8 @@ extern "C" { ...@@ -35,9 +35,8 @@ extern "C" {
35 struct _locker; 35 struct _locker;
36 typedef struct _locker *locker_t; 36 typedef struct _locker *locker_t;
37 37
38 extern int locker_add_ref __P ((locker_t)); 38 extern int locker_ref __P ((locker_t));
39 extern int locker_release __P ((locker_t)); 39 extern void locker_destroy __P ((locker_t *));
40 extern int locker_destroy __P ((locker_t));
41 40
42 extern int locker_lock __P ((locker_t)); 41 extern int locker_lock __P ((locker_t));
43 extern int locker_touchlock __P ((locker_t)); 42 extern int locker_touchlock __P ((locker_t));
......
...@@ -46,18 +46,17 @@ extern "C" { ...@@ -46,18 +46,17 @@ extern "C" {
46 #endif /*__P */ 46 #endif /*__P */
47 47
48 /* Constructor/destructor and possible types. */ 48 /* Constructor/destructor and possible types. */
49 extern int mailbox_add_ref __P ((mailbox_t)); 49 extern int mailbox_ref __P ((mailbox_t));
50 extern int mailbox_release __P ((mailbox_t)); 50 extern void mailbox_destroy __P ((mailbox_t *));
51 extern int mailbox_destroy __P ((mailbox_t));
52 extern int mailbox_get_folder __P ((mailbox_t, folder_t *)); 51 extern int mailbox_get_folder __P ((mailbox_t, folder_t *));
53 52
54 extern int mailbox_open __P ((mailbox_t, int flag)); 53 extern int mailbox_open __P ((mailbox_t, int));
55 extern int mailbox_close __P ((mailbox_t)); 54 extern int mailbox_close __P ((mailbox_t));
56 extern int mailbox_uidvalidity __P ((mailbox_t, unsigned long *)); 55 extern int mailbox_uidvalidity __P ((mailbox_t, unsigned long *));
57 extern int mailbox_uidnext __P ((mailbox_t, size_t *)); 56 extern int mailbox_uidnext __P ((mailbox_t, size_t *));
58 57
59 /* Messages. */ 58 /* Messages. */
60 extern int mailbox_get_message __P ((mailbox_t, size_t msgno, message_t *)); 59 extern int mailbox_get_message __P ((mailbox_t, size_t, message_t *));
61 extern int mailbox_append_message __P ((mailbox_t, message_t)); 60 extern int mailbox_append_message __P ((mailbox_t, message_t));
62 extern int mailbox_messages_count __P ((mailbox_t, size_t *)); 61 extern int mailbox_messages_count __P ((mailbox_t, size_t *));
63 extern int mailbox_messages_recent __P ((mailbox_t, size_t *)); 62 extern int mailbox_messages_recent __P ((mailbox_t, size_t *));
...@@ -66,9 +65,9 @@ extern int mailbox_expunge __P ((mailbox_t)); ...@@ -66,9 +65,9 @@ extern int mailbox_expunge __P ((mailbox_t));
66 extern int mailbox_save_attributes __P ((mailbox_t)); 65 extern int mailbox_save_attributes __P ((mailbox_t));
67 66
68 /* Update and scanning. */ 67 /* Update and scanning. */
69 extern int mailbox_get_size __P ((mailbox_t, off_t *size)); 68 extern int mailbox_get_size __P ((mailbox_t, off_t *));
70 extern int mailbox_is_updated __P ((mailbox_t)); 69 extern int mailbox_is_updated __P ((mailbox_t));
71 extern int mailbox_scan __P ((mailbox_t, size_t no, size_t *count)); 70 extern int mailbox_scan __P ((mailbox_t, size_t, size_t *));
72 71
73 /* Mailbox Stream. */ 72 /* Mailbox Stream. */
74 extern int mailbox_get_stream __P ((mailbox_t, stream_t *)); 73 extern int mailbox_get_stream __P ((mailbox_t, stream_t *));
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
18 #ifndef _MAILUTILS_MBOX_H 18 #ifndef _MAILUTILS_MBOX_H
19 #define _MAILUTILS_MBOX_H 19 #define _MAILUTILS_MBOX_H
20 20
21 #include <mailutils/message.h> 21 #include <mailutils/stream.h>
22 #include <mailutils/observable.h> 22 #include <mailutils/attribute.h>
23 23
24 #ifdef __cplusplus 24 #ifdef __cplusplus
25 extern "C" { 25 extern "C" {
...@@ -38,32 +38,48 @@ typedef struct _mbox *mbox_t; ...@@ -38,32 +38,48 @@ typedef struct _mbox *mbox_t;
38 38
39 39
40 extern int mbox_create __P ((mbox_t *)); 40 extern int mbox_create __P ((mbox_t *));
41 extern int mbox_destroy __P ((mbox_t)); 41 extern void mbox_destroy __P ((mbox_t *));
42 42
43 extern int mbox_uidvalidity __P ((mbox_t, unsigned long *)); 43 extern int mbox_get_uidvalidity __P ((mbox_t, unsigned long *));
44 extern int mbox_uidnext __P ((mbox_t, unsigned long)); 44 extern int mbox_get_uidnext __P ((mbox_t, unsigned long));
45 45
46 extern int mbox_open __P ((mbox_t, const char *, int)); 46 extern int mbox_open __P ((mbox_t, const char *, int));
47 extern int mbox_close __P ((mbox_t)); 47 extern int mbox_close __P ((mbox_t));
48 48
49 extern int mbox_get_message __P ((mbox_t, unsigned int, message_t *)); 49 extern int mbox_get_attribute __P ((mbox_t, unsigned int, attribute_t *));
50 extern int mbox_get_envelope __P ((mbox_t, unsigned int, envelope_t *)); 50 extern int mbox_get_uid __P ((mbox_t, unsigned int, unsigned long *));
51 extern int mbox_get_header __P ((mbox_t, unsigned int, header_t *));
52 extern int mbox_get_body __P ((mbox_t, unsigned int, body_t *));
53 51
54 extern int mbox_get_flags __P ((mbox_t, unsigned int, int *)); 52 extern int mbox_get_separator __P ((mbox_t, unsigned int, char **));
53 extern int mbox_set_separator __P ((mbox_t, unsigned int, const char *));
54
55 extern int mbox_get_hstream __P ((mbox_t, unsigned int, stream_t *));
56 extern int mbox_set_hstream __P ((mbox_t, unsigned int, stream_t));
57 extern int mbox_get_hsize __P ((mbox_t, unsigned int, unsigned *));
58 extern int mbox_get_hlines __P ((mbox_t, unsigned int, unsigned *));
59
60 extern int mbox_get_bstream __P ((mbox_t, unsigned int, stream_t *));
61 extern int mbox_set_bstream __P ((mbox_t, unsigned int, stream_t));
62 extern int mbox_get_bsize __P ((mbox_t, unsigned int, unsigned *));
63 extern int mbox_get_blines __P ((mbox_t, unsigned int, unsigned *));
55 64
56 extern int mbox_get_size __P ((mbox_t, unsigned long *)); 65 extern int mbox_get_size __P ((mbox_t, unsigned long *));
57 66
58 extern int mbox_save_attributes __P ((mbox_t)); 67 extern int mbox_save_attributes __P ((mbox_t));
68 extern int mbox_mark_deleted __P ((mbox_t, unsigned int));
69 extern int mbox_unmark_deleted __P ((mbox_t, unsigned int));
59 extern int mbox_expunge __P ((mbox_t)); 70 extern int mbox_expunge __P ((mbox_t));
60 extern int mbox_is_modified __P ((mbox_t)); 71 extern int mbox_is_modified __P ((mbox_t));
61 72
73 extern int mbox_set_progress_cb __P ((mbox_t, int (*) __P ((int, void *)), void *));
74 extern int mbox_set_newmsg_cb __P ((mbox_t, int (*) __P ((int, void *)), void *));
75 extern int mbox_newmsg_cb __P ((mbox_t, int));
76 extern int mbox_progress_cb __P ((mbox_t, int));
77
62 extern int mbox_scan __P ((mbox_t, unsigned int, unsigned int *)); 78 extern int mbox_scan __P ((mbox_t, unsigned int, unsigned int *));
63 extern int mbox_messages_count __P ((mbox_t, unsigned int *)); 79 extern int mbox_messages_count __P ((mbox_t, unsigned int *));
64 extern int mbox_get_obervable __P ((mbox_t, observable_t *));
65 80
66 extern int mbox_append __P ((mbox_t, message_t)); 81 extern int mbox_append __P ((mbox_t, const char *, stream_t));
82 extern int mbox_append_hb __P ((mbox_t, const char *, stream_t, stream_t));
67 83
68 84
69 #ifdef __cplusplus 85 #ifdef __cplusplus
......
...@@ -46,9 +46,8 @@ extern "C" { ...@@ -46,9 +46,8 @@ extern "C" {
46 /* A message is considered to be a container for: 46 /* A message is considered to be a container for:
47 header_t, body_t, and its attribute_t. */ 47 header_t, body_t, and its attribute_t. */
48 48
49 extern int message_add_ref __P ((message_t)); 49 extern int message_ref __P ((message_t));
50 extern int message_release __P ((message_t)); 50 extern void message_destroy __P ((message_t *));
51 extern int message_destroy __P ((message_t));
52 51
53 extern int message_is_modified __P ((message_t)); 52 extern int message_is_modified __P ((message_t));
54 extern int message_clear_modified __P ((message_t)); 53 extern int message_clear_modified __P ((message_t));
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
30 # define MU_MONITOR_INITIALIZER PTHREAD_MUTEX_INITIALIZER 30 # define MU_MONITOR_INITIALIZER PTHREAD_MUTEX_INITIALIZER
31 31
32 # define monitor_create(m) pthread_mutex_init (m, NULL) 32 # define monitor_create(m) pthread_mutex_init (m, NULL)
33 # define monitor_destroy(m) pthread_mutex_destroy (&m) 33 # define monitor_destroy(m) pthread_mutex_destroy (m)
34 34
35 # define monitor_cleanup_push(routine, arg) pthread_cleanup_push (routine, arg) 35 # define monitor_cleanup_push(routine, arg) pthread_cleanup_push (routine, arg)
36 # define monitor_cleanup_pop(execute) pthread_cleanup_pop (execute) 36 # define monitor_cleanup_pop(execute) pthread_cleanup_pop (execute)
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
45 # define MU_MONITOR_INITIALIZER 0 45 # define MU_MONITOR_INITIALIZER 0
46 46
47 # define monitor_create(m) (*m = 0) 47 # define monitor_create(m) (*m = 0)
48 # define monitor_destroy(m) (m = 0) 48 # define monitor_destroy(m) (*m = 0)
49 49
50 # define monitor_cleanup_push(routine, arg) { 50 # define monitor_cleanup_push(routine, arg) {
51 # define monitor_cleanup_pop(execute) } 51 # define monitor_cleanup_pop(execute) }
......
...@@ -64,6 +64,15 @@ extern char * mu_tilde_expansion __P ((const char *ref, const char *delim, const ...@@ -64,6 +64,15 @@ extern char * mu_tilde_expansion __P ((const char *ref, const char *delim, const
64 64
65 extern size_t util_cpystr __P ((char *dst, const char *src, size_t size)); 65 extern size_t util_cpystr __P ((char *dst, const char *src, size_t size));
66 66
67 struct passwd;
68
69 extern void mu_register_getpwnam __P((struct passwd *(*fun) __P((const char *))));
70 extern struct passwd * mu_getpwnam __P((const char *name));
71
72 extern int mu_virtual_domain;
73
74 extern struct passwd * getpwnam_virtual __P((const char *u));
75
67 #ifdef __cplusplus 76 #ifdef __cplusplus
68 } 77 }
69 #endif 78 #endif
......
...@@ -37,8 +37,7 @@ struct _observable; ...@@ -37,8 +37,7 @@ struct _observable;
37 typedef struct _observable *observable_t; 37 typedef struct _observable *observable_t;
38 38
39 extern int observable_create __P ((observable_t *)); 39 extern int observable_create __P ((observable_t *));
40 extern int observable_release __P ((observable_t)); 40 extern void observable_destroy __P ((observable_t *));
41 extern int observable_destroy __P ((observable_t));
42 41
43 extern int observable_attach __P ((observable_t, int, observer_t)); 42 extern int observable_attach __P ((observable_t, int, observer_t));
44 extern int observable_detach __P ((observable_t, observer_t)); 43 extern int observable_detach __P ((observable_t, observer_t));
......
...@@ -56,10 +56,8 @@ struct event ...@@ -56,10 +56,8 @@ struct event
56 extern int observer_create __P ((observer_t *, int (*action) 56 extern int observer_create __P ((observer_t *, int (*action)
57 __P ((void *, struct event)), void *)); 57 __P ((void *, struct event)), void *));
58 58
59 extern int observer_add_ref __P ((observer_t)); 59 extern int observer_ref __P ((observer_t));
60 extern int observer_release __P ((observer_t)); 60 extern void observer_destroy __P ((observer_t *));
61 extern int observer_destroy __P ((observer_t));
62
63 extern int observer_action __P ((observer_t, struct event)); 61 extern int observer_action __P ((observer_t, struct event));
64 62
65 #ifdef __cplusplus 63 #ifdef __cplusplus
......
...@@ -37,7 +37,7 @@ struct _pop3; ...@@ -37,7 +37,7 @@ struct _pop3;
37 typedef struct _pop3* pop3_t; 37 typedef struct _pop3* pop3_t;
38 38
39 extern int pop3_create __P ((pop3_t *)); 39 extern int pop3_create __P ((pop3_t *));
40 extern int pop3_destroy __P ((pop3_t)); 40 extern void pop3_destroy __P ((pop3_t *));
41 41
42 extern int pop3_connect __P ((pop3_t, const char *, unsigned int)); 42 extern int pop3_connect __P ((pop3_t, const char *, unsigned int));
43 extern int pop3_disconnect __P ((pop3_t)); 43 extern int pop3_disconnect __P ((pop3_t));
......
...@@ -36,7 +36,7 @@ struct _property; ...@@ -36,7 +36,7 @@ struct _property;
36 typedef struct _property *property_t; 36 typedef struct _property *property_t;
37 37
38 extern int property_create __P ((property_t *)); 38 extern int property_create __P ((property_t *));
39 extern int property_destroy __P ((property_t)); 39 extern void property_destroy __P ((property_t *));
40 40
41 extern int property_set_value __P ((property_t, const char *, const char *, 41 extern int property_set_value __P ((property_t, const char *, const char *,
42 int)); 42 int));
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 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 _MAILUTILS_REFCOUNT_H
19 #define _MAILUTILS_REFCOUNT_H
20
21 #include <sys/types.h>
22
23 #ifndef __P
24 #ifdef __STDC__
25 #define __P(args) args
26 #else
27 #define __P(args) ()
28 #endif
29 #endif /*__P */
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /* forward declaration */
36 struct _refcount;
37 typedef struct _refcount *mu_refcount_t;
38
39 extern int mu_refcount_create __P ((mu_refcount_t *));
40 extern void mu_refcount_destroy __P ((mu_refcount_t *));
41 extern int mu_refcount_inc __P ((mu_refcount_t));
42 extern int mu_refcount_dec __P ((mu_refcount_t));
43 extern int mu_refcount_lock __P ((mu_refcount_t));
44 extern int mu_refcount_unlock __P ((mu_refcount_t));
45
46 #ifdef __cplusplus
47 }
48 #endif
49
50 #endif /* _MAILUTILS_REFCOUNT_H */
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
19 #define _MAILUTILS_STREAM_H 19 #define _MAILUTILS_STREAM_H
20 20
21 #include <sys/types.h> 21 #include <sys/types.h>
22 #include <stdio.h>
22 23
23 #ifdef __cplusplus 24 #ifdef __cplusplus
24 extern "C" { 25 extern "C" {
...@@ -50,9 +51,8 @@ enum stream_state ...@@ -50,9 +51,8 @@ enum stream_state
50 struct _stream; 51 struct _stream;
51 typedef struct _stream *stream_t; 52 typedef struct _stream *stream_t;
52 53
53 extern int stream_add_ref __P ((stream_t)); 54 extern int stream_ref __P ((stream_t));
54 extern int stream_release __P ((stream_t)); 55 extern void stream_destroy __P ((stream_t *));
55 extern int stream_destroy __P ((stream_t));
56 56
57 extern int stream_open __P ((stream_t, const char *, int, int)); 57 extern int stream_open __P ((stream_t, const char *, int, int));
58 extern int stream_close __P ((stream_t)); 58 extern int stream_close __P ((stream_t));
...@@ -80,9 +80,11 @@ extern int stream_is_open __P ((stream_t)); ...@@ -80,9 +80,11 @@ extern int stream_is_open __P ((stream_t));
80 80
81 /* Misc. */ 81 /* Misc. */
82 extern int stream_file_create __P ((stream_t *)); 82 extern int stream_file_create __P ((stream_t *));
83 extern int stream_stdio_create __P ((stream_t *, FILE *));
83 extern int stream_mapfile_create __P ((stream_t *)); 84 extern int stream_mapfile_create __P ((stream_t *));
84 extern int stream_memory_create __P ((stream_t *)); 85 extern int stream_memory_create __P ((stream_t *));
85 extern int stream_tcp_create __P ((stream_t *)); 86 extern int stream_tcp_create __P ((stream_t *));
87 extern int stream_fd_create __P ((stream_t *, int));
86 extern int stream_buffer_create __P ((stream_t *, stream_t, size_t)); 88 extern int stream_buffer_create __P ((stream_t *, stream_t, size_t));
87 89
88 #ifdef __cplusplus 90 #ifdef __cplusplus
......
...@@ -20,6 +20,7 @@ pkginclude_HEADERS = \ ...@@ -20,6 +20,7 @@ pkginclude_HEADERS = \
20 observable.h \ 20 observable.h \
21 observer.h \ 21 observer.h \
22 pop3.h \ 22 pop3.h \
23 refcount.h \
23 stream.h \ 24 stream.h \
24 tcpstream.h \ 25 tcpstream.h \
25 ticket.h \ 26 ticket.h \
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
23 #endif 23 #endif
24 24
25 #include <mailutils/attribute.h> 25 #include <mailutils/attribute.h>
26 #include <mailutils/monitor.h> 26 #include <mailutils/refcount.h>
27 27
28 #ifdef __cplusplus 28 #ifdef __cplusplus
29 extern "C" { 29 extern "C" {
...@@ -39,9 +39,8 @@ extern "C" { ...@@ -39,9 +39,8 @@ extern "C" {
39 39
40 struct _attribute_vtable 40 struct _attribute_vtable
41 { 41 {
42 int (*add_ref) __P ((attribute_t)); 42 int (*ref) __P ((attribute_t));
43 int (*release) __P ((attribute_t)); 43 void (*destroy) __P ((attribute_t *));
44 int (*destroy) __P ((attribute_t));
45 44
46 int (*get_flags) __P ((attribute_t, int *)); 45 int (*get_flags) __P ((attribute_t, int *));
47 int (*set_flags) __P ((attribute_t, int)); 46 int (*set_flags) __P ((attribute_t, int));
...@@ -58,9 +57,8 @@ struct _attribute ...@@ -58,9 +57,8 @@ struct _attribute
58 struct _da 57 struct _da
59 { 58 {
60 struct _attribute base; 59 struct _attribute base;
61 int ref; 60 mu_refcount_t refcount;
62 int flags; 61 int flags;
63 monitor_t lock;
64 }; 62 };
65 63
66 #ifdef __cplusplus 64 #ifdef __cplusplus
......
...@@ -38,9 +38,8 @@ extern "C" { ...@@ -38,9 +38,8 @@ extern "C" {
38 38
39 struct _authority_vtable 39 struct _authority_vtable
40 { 40 {
41 int (*add_ref) __P ((authority_t)); 41 int (*ref) __P ((authority_t));
42 int (*release) __P ((authority_t)); 42 void (*destroy) __P ((authority_t *));
43 int (*destroy) __P ((authority_t));
44 43
45 int (*set_ticket) __P ((authority_t, ticket_t)); 44 int (*set_ticket) __P ((authority_t, ticket_t));
46 int (*get_ticket) __P ((authority_t, ticket_t *)); 45 int (*get_ticket) __P ((authority_t, ticket_t *));
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 #define MAILUTILS_SYS_BSTREAM_H 19 #define MAILUTILS_SYS_BSTREAM_H
20 20
21 #include <mailutils/sys/stream.h> 21 #include <mailutils/sys/stream.h>
22 #include <mailutils/monitor.h> 22 #include <mailutils/refcount.h>
23 23
24 /* Read buffer */ 24 /* Read buffer */
25 struct _rbuffer 25 struct _rbuffer
...@@ -33,10 +33,9 @@ struct _rbuffer ...@@ -33,10 +33,9 @@ struct _rbuffer
33 struct _bs 33 struct _bs
34 { 34 {
35 struct _stream base; 35 struct _stream base;
36 int ref; 36 mu_refcount_t refcount;
37 stream_t stream; 37 stream_t stream;
38 struct _rbuffer rbuffer; 38 struct _rbuffer rbuffer;
39 monitor_t lock;
40 }; 39 };
41 40
42 #endif /* _MAILUTILS_SYS_BSTREAM_H */ 41 #endif /* _MAILUTILS_SYS_BSTREAM_H */
......
...@@ -38,12 +38,14 @@ extern "C" { ...@@ -38,12 +38,14 @@ extern "C" {
38 38
39 struct _envelope_vtable 39 struct _envelope_vtable
40 { 40 {
41 int (*add_ref) __P ((envelope_t)); 41 int (*ref) __P ((envelope_t));
42 int (*release) __P ((envelope_t)); 42 void (*destroy) __P ((envelope_t *));
43 int (*destroy) __P ((envelope_t)); 43 int (*get_sender) __P ((envelope_t, address_t *));
44 int (*sender) __P ((envelope_t, address_t *)); 44 int (*set_sender) __P ((envelope_t, address_t));
45 int (*recipient) __P ((envelope_t, address_t *)); 45 int (*get_recipient) __P ((envelope_t, address_t *));
46 int (*date) __P ((envelope_t, struct tm *, struct mu_timezone *)); 46 int (*set_recipient) __P ((envelope_t, address_t));
47 int (*get_date) __P ((envelope_t, struct tm *, struct mu_timezone *));
48 int (*set_date) __P ((envelope_t, struct tm *, struct mu_timezone *));
47 }; 49 };
48 50
49 struct _envelope 51 struct _envelope
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 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 Library General 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 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 MAILUTILS_SYS_FDSTREAM_H
19 #define MAILUTILS_SYS_FDSTREAM_H
20
21 #include <mailutils/refcount.h>
22 #include <mailutils/sys/stream.h>
23
24 struct _fds
25 {
26 struct _stream base;
27 mu_refcount_t refcount;
28 int fd;
29 int state;
30 int flags;
31 };
32
33 #endif /* _MAILUTILS_SYS_FDSTREAM_H */
...@@ -35,9 +35,8 @@ extern "C" { ...@@ -35,9 +35,8 @@ extern "C" {
35 35
36 struct _folder_vtable 36 struct _folder_vtable
37 { 37 {
38 int (*add_ref) __P ((folder_t)); 38 int (*ref) __P ((folder_t));
39 int (*release) __P ((folder_t)); 39 void (*destroy) __P ((folder_t *));
40 int (*destroy) __P ((folder_t));
41 40
42 int (*open) __P ((folder_t, int flag)); 41 int (*open) __P ((folder_t, int flag));
43 int (*close) __P ((folder_t)); 42 int (*close) __P ((folder_t));
......
...@@ -19,15 +19,14 @@ ...@@ -19,15 +19,14 @@
19 #define MAILUTILS_SYS_FSTREAM_H 19 #define MAILUTILS_SYS_FSTREAM_H
20 20
21 #include <mailutils/sys/stream.h> 21 #include <mailutils/sys/stream.h>
22 #include <mailutils/monitor.h> 22 #include <mailutils/refcount.h>
23 23
24 struct _fs 24 struct _fs
25 { 25 {
26 struct _stream base; 26 struct _stream base;
27 int ref; 27 mu_refcount_t refcount;
28 int flags; 28 int flags;
29 FILE *file; 29 FILE *file;
30 monitor_t lock;
31 }; 30 };
32 31
33 #endif /* _MAILUTILS_SYS_FSTREAM_H */ 32 #endif /* _MAILUTILS_SYS_FSTREAM_H */
......
...@@ -34,9 +34,8 @@ extern "C" { ...@@ -34,9 +34,8 @@ extern "C" {
34 34
35 struct _header_vtable 35 struct _header_vtable
36 { 36 {
37 int (*add_ref) __P ((header_t)); 37 int (*ref) __P ((header_t));
38 int (*release) __P ((header_t)); 38 void (*destroy) __P ((header_t *));
39 int (*destroy) __P ((header_t));
40 39
41 int (*is_modified) __P ((header_t)); 40 int (*is_modified) __P ((header_t));
42 int (*clear_modified) __P ((header_t)); 41 int (*clear_modified) __P ((header_t));
......
...@@ -27,9 +27,8 @@ extern "C" { ...@@ -27,9 +27,8 @@ extern "C" {
27 struct _iterator_vtable 27 struct _iterator_vtable
28 { 28 {
29 /* Base */ 29 /* Base */
30 int (*add_ref) __P ((iterator_t)); 30 int (*ref) __P ((iterator_t));
31 int (*release) __P ((iterator_t)); 31 void (*destroy) __P ((iterator_t *));
32 int (*destroy) __P ((iterator_t));
33 32
34 int (*first) __P ((iterator_t)); 33 int (*first) __P ((iterator_t));
35 int (*next) __P ((iterator_t)); 34 int (*next) __P ((iterator_t));
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 #include <sys/types.h> 25 #include <sys/types.h>
26 26
27 #include <mailutils/list.h> 27 #include <mailutils/list.h>
28 #include <mailutils/monitor.h> 28 #include <mailutils/refcount.h>
29 #include <mailutils/sys/iterator.h> 29 #include <mailutils/sys/iterator.h>
30 30
31 #ifndef __P 31 #ifndef __P
...@@ -52,16 +52,15 @@ struct _list ...@@ -52,16 +52,15 @@ struct _list
52 struct mu_list_data head; 52 struct mu_list_data head;
53 size_t count; 53 size_t count;
54 size_t index; 54 size_t index;
55 monitor_t lock; 55 mu_refcount_t refcount;
56 }; 56 };
57 57
58 struct l_iterator 58 struct l_iterator
59 { 59 {
60 struct _iterator base; 60 struct _iterator base;
61 unsigned int ref;
62 mu_list_t list; 61 mu_list_t list;
63 struct mu_list_data *current; 62 struct mu_list_data *current;
64 monitor_t lock; 63 mu_refcount_t refcount;
65 }; 64 };
66 65
67 66
......
...@@ -38,9 +38,8 @@ extern "C" { ...@@ -38,9 +38,8 @@ extern "C" {
38 38
39 struct _locker_vtable 39 struct _locker_vtable
40 { 40 {
41 int (*add_ref) __P ((locker_t)); 41 int (*ref) __P ((locker_t));
42 int (*release) __P ((locker_t)); 42 void (*destroy) __P ((locker_t *));
43 int (*destroy) __P ((locker_t));
44 43
45 int (*lock) __P ((locker_t)); 44 int (*lock) __P ((locker_t));
46 int (*touchlock) __P ((locker_t)); 45 int (*touchlock) __P ((locker_t));
......
...@@ -35,9 +35,8 @@ extern "C" { ...@@ -35,9 +35,8 @@ extern "C" {
35 struct _mailbox_vtable 35 struct _mailbox_vtable
36 { 36 {
37 /* Constructor/destructor and possible types. */ 37 /* Constructor/destructor and possible types. */
38 int (*add_ref) __P ((mailbox_t)); 38 int (*ref) __P ((mailbox_t));
39 int (*release) __P ((mailbox_t)); 39 void (*destroy) __P ((mailbox_t *));
40 int (*destroy) __P ((mailbox_t));
41 int (*get_folder) __P ((mailbox_t, folder_t *)); 40 int (*get_folder) __P ((mailbox_t, folder_t *));
42 41
43 int (*open) __P ((mailbox_t, int flag)); 42 int (*open) __P ((mailbox_t, int flag));
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
19 #define _MAILUTILS_SYS_MBOX_H 19 #define _MAILUTILS_SYS_MBOX_H
20 20
21 #include <time.h> 21 #include <time.h>
22 #include <mailutils/monitor.h>
23 #include <mailutils/locker.h> 22 #include <mailutils/locker.h>
24 #include <mailutils/mbox.h> 23 #include <mailutils/mbox.h>
25 24
...@@ -29,68 +28,33 @@ extern "C" { ...@@ -29,68 +28,33 @@ extern "C" {
29 28
30 typedef struct _mbox_message* mbox_message_t; 29 typedef struct _mbox_message* mbox_message_t;
31 30
32 /* Below are the headers field-names that we are caching for speed, it is
33 more or less the list of headers in ENVELOPE command from IMAP. */
34 #define HDRSIZE 15
35
36 const char *fhdr_table[] =
37 {
38 #define H_BCC 0
39 "Bcc",
40 #define H_CC 1
41 "Cc",
42 #define H_CONTENT_LANGUAGE 2
43 "Content-Language",
44 #define H_CONTENT_TRANSFER_ENCODING 3
45 "Content-Transfer-Encoding",
46 #define H_CONTENT_TYPE 4
47 "Content-Type",
48 #define H_DATE 5
49 "Date",
50 #define H_FROM 6
51 "From",
52 #define H_IN_REPLY_TO 7
53 "In-Reply-To",
54 #define H_MESSAGE_ID 8
55 "Message-ID",
56 #define H_REFERENCE 9
57 "Reply-To",
58 #define H_REPLY_TO 10
59 "Reply-To",
60 #define H_SENDER 11
61 "Sender",
62 #define H_SUBJECT 12
63 "Subject",
64 #define H_TO 13
65 "To",
66 #define H_X_UIDL 14
67 "X-UIDL"
68 };
69 31
70 /* Keep the file positions of where the headers and bodies start and end. 32 /* Keep the file positions of where the headers and bodies start and end.
71 attr_flags is the "Status:" message. */ 33 attribute is the "Status:" message. */
72 struct _mbox_message 34 struct _mbox_message
73 { 35 {
74 /* Offset of the messages in the mailbox. */ 36 /* Offset of the messages in the mailbox. */
75 off_t header_from; 37 off_t from_;
76 off_t header_from_end;
77 off_t body;
78 off_t body_end;
79 38
80 /* Fast header retrieve, we save here the most common headers. This will 39 /* Fast header retrieve, we save here the most common headers. This will
81 speed the header search. The entire headers are copied, when modified, 40 speed the header search. The entire headers are copied, when modified,
82 by the header_t object, we do not have to worry about updating them. */ 41 by the header_t object, we do not have to worry about updating them. */
83 char *fhdr[HDRSIZE]; 42 char **fhdr;
84 43
85 size_t uid; /* IMAP uid. */ 44 struct
86 45 {
87 int attr_flags; /* The attr_flags contains the "Status:" attribute */ 46 stream_t stream;
47 unsigned int lines;
48 unsigned int size;
49 off_t start;
50 off_t end;
51 } header, body;
88 52
89 size_t header_lines; 53 /* UID i.e. see IMAP */
90 size_t body_lines; 54 unsigned long uid;
55 attribute_t attribute; /* The attr_flags contains the "Status:" attribute */
91 56
92 message_t message; /* A message attach to it. */ 57 mbox_t mbox; /* Back pointer. */
93 mbox_t mud; /* Back pointer. */
94 }; 58 };
95 59
96 /* The umessages is an array of pointers that contains umessages_count of 60 /* The umessages is an array of pointers that contains umessages_count of
...@@ -101,10 +65,12 @@ struct _mbox_message ...@@ -101,10 +65,12 @@ struct _mbox_message
101 struct _mbox 65 struct _mbox
102 { 66 {
103 mbox_message_t *umessages; /* Array. */ 67 mbox_message_t *umessages; /* Array. */
104 size_t umessages_count; /* How big is the umessages[]. */ 68 unsigned int umessages_count; /* How big is the umessages[]. */
105 size_t messages_count; /* How many valid entry in umessages[]. */ 69
70 unsigned int messages_count; /* Number of messages. */
71
72 stream_t carrier; /* File stream. */
106 73
107 stream_t stream;
108 off_t size; /* Size of the mailbox. */ 74 off_t size; /* Size of the mailbox. */
109 time_t mtime; /* Modified time. */ 75 time_t mtime; /* Modified time. */
110 unsigned long uidvalidity; 76 unsigned long uidvalidity;
...@@ -115,32 +81,18 @@ struct _mbox ...@@ -115,32 +81,18 @@ struct _mbox
115 enum mbox_state 81 enum mbox_state
116 { 82 {
117 MBOX_NO_STATE = 0, 83 MBOX_NO_STATE = 0,
118 MBOX_STATE_APPEND_SENDER, MBOX_STATE_APPEND_DATE, MBOX_STATE_APPEND_HEADER, 84 MBOX_STATE_APPEND_HEADER,
119 MBOX_STATE_APPEND_ATTRIBUTE, MBOX_STATE_APPEND_UID, MBOX_STATE_APPEND_BODY, 85 MBOX_STATE_APPEND_BODY
120 MBOX_STATE_APPEND_MESSAGE
121 } state ; 86 } state ;
122 char *sender;
123 char *to;
124 char *date;
125 off_t off;
126 monitor_t lock;
127 87
128 mu_debug_t debug;
129 locker_t locker; 88 locker_t locker;
130 observable_t observable;
131 };
132 89
133 /* Moro(?)ic kluge. */ 90 struct
134 #define MBOX_DEBUG0(mbox, type, format) \ 91 {
135 if (mbox->debug) mu_debug_print (mbox->debug, type, format) 92 int (*cb) __P ((int, void *));
136 #define MBOX_DEBUG1(mbox, type, format, arg1) \ 93 void *arg;
137 if (mbox->debug) mu_debug_print (mbox->debug, type, format, arg1) 94 } newmsg, progress, corrupt;
138 #define MBOX_DEBUG2(mbox, type, format, arg1, arg2) \ 95 };
139 if (mbox->debug) mu_debug_print (mbox->debug, type, format, arg1, arg2)
140 #define MBOX_DEBUG3(mbox, type, format, arg1, arg2, arg3) \
141 if (mbox->debug) mu_debug_print (mbox->debug, type, format, arg1, arg2, arg3)
142 #define MBOX_DEBUG4(mbox, type, format, arg1, arg2, arg3, arg4) \
143 if (mbox->debug) mu_debug_print (mbox->debug, type, format, arg1, arg2, arg3, arg4)
144 96
145 #ifdef __cplusplus 97 #ifdef __cplusplus
146 } 98 }
......
...@@ -20,18 +20,17 @@ ...@@ -20,18 +20,17 @@
20 20
21 #include <sys/types.h> 21 #include <sys/types.h>
22 22
23 #include <mailutils/monitor.h> 23 #include <mailutils/refcount.h>
24 #include <mailutils/sys/stream.h> 24 #include <mailutils/sys/stream.h>
25 25
26 struct _memory_stream 26 struct _memory_stream
27 { 27 {
28 struct _stream base; 28 struct _stream base;
29 int ref; 29 mu_refcount_t refcount;
30 char *ptr; 30 char *ptr;
31 size_t size; 31 size_t size;
32 off_t offset; 32 off_t offset;
33 int flags; 33 int flags;
34 monitor_t lock;
35 }; 34 };
36 35
37 #endif /* _MAILUTILS_SYS_MEMSTREAM_H */ 36 #endif /* _MAILUTILS_SYS_MEMSTREAM_H */
......
...@@ -37,9 +37,8 @@ extern "C" { ...@@ -37,9 +37,8 @@ extern "C" {
37 37
38 struct _message_vtable 38 struct _message_vtable
39 { 39 {
40 int (*add_ref) __P ((message_t)); 40 int (*ref) __P ((message_t));
41 int (*release) __P ((message_t)); 41 void (*destroy) __P ((message_t *));
42 int (*destroy) __P ((message_t));
43 42
44 int (*is_modified) __P ((message_t)); 43 int (*is_modified) __P ((message_t));
45 int (*clear_modified) __P ((message_t)); 44 int (*clear_modified) __P ((message_t));
......
...@@ -19,19 +19,18 @@ ...@@ -19,19 +19,18 @@
19 #define MAILUTILS_SYS_MSTREAM_H 19 #define MAILUTILS_SYS_MSTREAM_H
20 20
21 #include <mailutils/sys/stream.h> 21 #include <mailutils/sys/stream.h>
22 #include <mailutils/monitor.h> 22 #include <mailutils/refcount.h>
23 23
24 struct _ms 24 struct _ms
25 { 25 {
26 struct _stream base; 26 struct _stream base;
27 int ref; 27 mu_refcount_t refcount;
28 int fd; 28 int fd;
29 int flags; 29 int flags;
30 int mflags; 30 int mflags;
31 char *ptr; 31 char *ptr;
32 size_t size; 32 size_t size;
33 off_t offset; 33 off_t offset;
34 monitor_t lock;
35 }; 34 };
36 35
37 #endif /* _MAILUTILS_SYS_MSTREAM_H */ 36 #endif /* _MAILUTILS_SYS_MSTREAM_H */
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
22 # include <dmalloc.h> 22 # include <dmalloc.h>
23 #endif 23 #endif
24 24
25 #include <mailutils/monitor.h>
26 #include <mailutils/list.h> 25 #include <mailutils/list.h>
27 #include <mailutils/observable.h> 26 #include <mailutils/observable.h>
28 27
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 # include <dmalloc.h> 22 # include <dmalloc.h>
23 #endif 23 #endif
24 24
25 #include <mailutils/monitor.h> 25 #include <mailutils/refcount.h>
26 #include <mailutils/observer.h> 26 #include <mailutils/observer.h>
27 #include <mailutils/list.h> 27 #include <mailutils/list.h>
28 28
...@@ -40,9 +40,8 @@ extern "C" { ...@@ -40,9 +40,8 @@ extern "C" {
40 40
41 struct _observer_vtable 41 struct _observer_vtable
42 { 42 {
43 int (*add_ref) __P ((observer_t)); 43 int (*ref) __P ((observer_t));
44 int (*release) __P ((observer_t)); 44 void (*destroy) __P ((observer_t *));
45 int (*destroy) __P ((observer_t));
46 45
47 int (*action) __P ((observer_t, struct event)); 46 int (*action) __P ((observer_t, struct event));
48 }; 47 };
...@@ -60,10 +59,9 @@ struct _observable ...@@ -60,10 +59,9 @@ struct _observable
60 struct _dobserver 59 struct _dobserver
61 { 60 {
62 struct _observer base; 61 struct _observer base;
63 int ref; 62 mu_refcount_t refcount;
64 void *arg; 63 void *arg;
65 int (*action) __P ((void *, struct event)); 64 int (*action) __P ((void *, struct event));
66 monitor_t lock;
67 }; 65 };
68 66
69 #ifdef __cplusplus 67 #ifdef __cplusplus
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 #include <mailutils/sys/stream.h> 24 #include <mailutils/sys/stream.h>
25 #include <mailutils/sys/iterator.h> 25 #include <mailutils/sys/iterator.h>
26 #include <mailutils/error.h> 26 #include <mailutils/error.h>
27 #include <mailutils/monitor.h> 27 #include <mailutils/refcount.h>
28 28
29 #ifdef DMALLOC 29 #ifdef DMALLOC
30 # include <dmalloc.h> 30 # include <dmalloc.h>
...@@ -59,19 +59,17 @@ struct p_iterator ...@@ -59,19 +59,17 @@ struct p_iterator
59 { 59 {
60 struct _iterator base; 60 struct _iterator base;
61 pop3_t pop3; 61 pop3_t pop3;
62 unsigned int ref; 62 mu_refcount_t refcount;
63 int done; 63 int done;
64 char *item; 64 char *item;
65 monitor_t lock;
66 }; 65 };
67 66
68 struct p_stream 67 struct p_stream
69 { 68 {
70 struct _stream base; 69 struct _stream base;
71 pop3_t pop3; 70 pop3_t pop3;
72 unsigned ref; 71 mu_refcount_t refcount;
73 int done; 72 int done;
74 monitor_t lock;
75 }; 73 };
76 74
77 struct work_buf 75 struct work_buf
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 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 _MAILUTILS_SYS_REFCOUNT_H
19 #define _MAILUTILS_SYS_REFCOUNT_H
20
21 #ifdef DMALLOC
22 #include <dmalloc.h>
23 #endif
24
25 #include <mailutils/refcount.h>
26 #include <mailutils/monitor.h>
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #ifndef __P
33 # ifdef __STDC__
34 # define __P(args) args
35 # else
36 # define __P(args) ()
37 # endif
38 #endif /*__P */
39
40 struct _refcount
41 {
42 unsigned int ref;
43 monitor_t lock;
44 };
45
46 #ifdef __cplusplus
47 }
48 #endif
49
50 #endif /* _MAILUTILS_SYS_REFCOUNT_H */
...@@ -26,9 +26,8 @@ extern "C" { ...@@ -26,9 +26,8 @@ extern "C" {
26 26
27 struct _stream_vtable 27 struct _stream_vtable
28 { 28 {
29 int (*add_ref) __P ((stream_t)); 29 int (*ref) __P ((stream_t));
30 int (*release) __P ((stream_t)); 30 void (*destroy) __P ((stream_t *));
31 int (*destroy) __P ((stream_t));
32 31
33 int (*open) __P ((stream_t, const char *, int, int)); 32 int (*open) __P ((stream_t, const char *, int, int));
34 int (*close) __P ((stream_t)); 33 int (*close) __P ((stream_t));
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 #ifndef MAILUTILS_SYS_TCP_H 18 #ifndef MAILUTILS_SYS_TCP_H
19 #define MAILUTILS_SYS_TCP_H 19 #define MAILUTILS_SYS_TCP_H
20 20
21 #include <mailutils/monitor.h> 21 #include <mailutils/refcount.h>
22 #include <mailutils/sys/stream.h> 22 #include <mailutils/sys/stream.h>
23 23
24 enum _tcp_state 24 enum _tcp_state
...@@ -33,14 +33,13 @@ enum _tcp_state ...@@ -33,14 +33,13 @@ enum _tcp_state
33 struct _tcp_instance 33 struct _tcp_instance
34 { 34 {
35 struct _stream base; 35 struct _stream base;
36 int ref; 36 mu_refcount_t refcount;
37 int fd; 37 int fd;
38 char *host; 38 char *host;
39 int port; 39 int port;
40 int state; 40 int state;
41 int flags; 41 int flags;
42 unsigned long address; 42 unsigned long address;
43 monitor_t lock;
44 }; 43 };
45 44
46 #endif /* _MAILUTILS_SYS_TCP_H */ 45 #endif /* _MAILUTILS_SYS_TCP_H */
......
...@@ -38,9 +38,8 @@ extern "C" { ...@@ -38,9 +38,8 @@ extern "C" {
38 38
39 struct _ticket_vtable 39 struct _ticket_vtable
40 { 40 {
41 int (*add_ref) __P ((ticket_t)); 41 int (*ref) __P ((ticket_t));
42 int (*release) __P ((ticket_t)); 42 void (*destroy) __P ((ticket_t *));
43 int (*destroy) __P ((ticket_t));
44 43
45 int (*pop) __P ((ticket_t, const char *, char **)); 44 int (*pop) __P ((ticket_t, const char *, char **));
46 }; 45 };
......
...@@ -36,9 +36,8 @@ extern "C" { ...@@ -36,9 +36,8 @@ extern "C" {
36 struct _ticket; 36 struct _ticket;
37 typedef struct _ticket *ticket_t; 37 typedef struct _ticket *ticket_t;
38 38
39 extern int ticket_add_ref __P ((ticket_t)); 39 extern int ticket_ref __P ((ticket_t));
40 extern int ticket_release __P ((ticket_t)); 40 extern void ticket_destroy __P ((ticket_t *));
41 extern int ticket_destroy __P ((ticket_t));
42 41
43 extern int ticket_pop __P ((ticket_t, const char *, char **)); 42 extern int ticket_pop __P ((ticket_t, const char *, char **));
44 43
......
...@@ -36,7 +36,7 @@ extern "C" { ...@@ -36,7 +36,7 @@ extern "C" {
36 struct _url; 36 struct _url;
37 typedef struct _url * url_t; 37 typedef struct _url * url_t;
38 38
39 extern int url_destroy __P ((url_t)); 39 extern void url_destroy __P ((url_t *));
40 extern int url_parse __P ((url_t)); 40 extern int url_parse __P ((url_t));
41 41
42 extern int url_get_scheme __P ((const url_t, char *, size_t, size_t *)); 42 extern int url_get_scheme __P ((const url_t, char *, size_t, size_t *));
......
...@@ -24,26 +24,20 @@ ...@@ -24,26 +24,20 @@
24 #include <mailutils/sys/iterator.h> 24 #include <mailutils/sys/iterator.h>
25 #include <mailutils/error.h> 25 #include <mailutils/error.h>
26 26
27 int 27 void
28 (iterator_release) (iterator_t iterator) 28 iterator_destroy (iterator_t *piterator)
29 { 29 {
30 if (iterator == NULL || iterator->vtable == NULL 30 if (piterator && *piterator)
31 || iterator->vtable->release == NULL) 31 {
32 return MU_ERROR_NOT_SUPPORTED; 32 iterator_t iterator = *piterator;
33 return iterator->vtable->release (iterator); 33 if (iterator->vtable && iterator->vtable->destroy)
34 } 34 iterator->vtable->destroy (piterator);
35 35 *piterator = NULL;
36 int 36 }
37 (iterator_destroy) (iterator_t iterator)
38 {
39 if (iterator == NULL || iterator->vtable == NULL
40 || iterator->vtable->destroy == NULL)
41 return MU_ERROR_NOT_SUPPORTED;
42 return iterator->vtable->destroy (iterator);
43 } 37 }
44 38
45 int 39 int
46 (iterator_first) (iterator_t iterator) 40 iterator_first (iterator_t iterator)
47 { 41 {
48 if (iterator == NULL || iterator->vtable == NULL 42 if (iterator == NULL || iterator->vtable == NULL
49 || iterator->vtable->first == NULL) 43 || iterator->vtable->first == NULL)
...@@ -52,7 +46,7 @@ int ...@@ -52,7 +46,7 @@ int
52 } 46 }
53 47
54 int 48 int
55 (iterator_next) (iterator_t iterator) 49 iterator_next (iterator_t iterator)
56 { 50 {
57 if (iterator == NULL || iterator->vtable == NULL 51 if (iterator == NULL || iterator->vtable == NULL
58 || iterator->vtable->next == NULL) 52 || iterator->vtable->next == NULL)
...@@ -61,7 +55,7 @@ int ...@@ -61,7 +55,7 @@ int
61 } 55 }
62 56
63 int 57 int
64 (iterator_current) (iterator_t iterator, void *pitem) 58 iterator_current (iterator_t iterator, void *pitem)
65 { 59 {
66 if (iterator == NULL || iterator->vtable == NULL 60 if (iterator == NULL || iterator->vtable == NULL
67 || iterator->vtable->current == NULL) 61 || iterator->vtable->current == NULL)
...@@ -70,7 +64,7 @@ int ...@@ -70,7 +64,7 @@ int
70 } 64 }
71 65
72 int 66 int
73 (iterator_is_done) (iterator_t iterator) 67 iterator_is_done (iterator_t iterator)
74 { 68 {
75 if (iterator == NULL || iterator->vtable == NULL 69 if (iterator == NULL || iterator->vtable == NULL
76 || iterator->vtable->is_done == NULL) 70 || iterator->vtable->is_done == NULL)
......
...@@ -38,8 +38,8 @@ mu_list_create (mu_list_t *plist) ...@@ -38,8 +38,8 @@ mu_list_create (mu_list_t *plist)
38 list = calloc (sizeof (*list), 1); 38 list = calloc (sizeof (*list), 1);
39 if (list == NULL) 39 if (list == NULL)
40 return ENOMEM; 40 return ENOMEM;
41 status = monitor_create (&(list->lock)); 41 status = mu_refcount_create (&(list->refcount));
42 if (status != 0) 42 if (list->refcount == NULL)
43 { 43 {
44 free (list); 44 free (list);
45 return status; 45 return status;
...@@ -52,26 +52,36 @@ mu_list_create (mu_list_t *plist) ...@@ -52,26 +52,36 @@ mu_list_create (mu_list_t *plist)
52 } 52 }
53 53
54 int 54 int
55 mu_list_destroy (mu_list_t list) 55 mu_list_ref (mu_list_t list)
56 { 56 {
57 if (list) 57 if (list)
58 return mu_refcount_inc (list->refcount);
59 return 0;
60 }
61 void
62 mu_list_destroy (mu_list_t *plist)
63 {
64 if (plist && *plist)
65 {
66 mu_list_t list = *plist;
67 if (mu_refcount_dec (list->refcount) == 0)
58 { 68 {
59 struct mu_list_data *current; 69 struct mu_list_data *current;
60 struct mu_list_data *previous; 70 struct mu_list_data *previous;
61 monitor_lock (list->lock); 71 mu_refcount_lock (list->refcount);
62 for (current = list->head.next; current != &(list->head);) 72 for (current = list->head.next; current != &(list->head);)
63 { 73 {
64 previous = current; 74 previous = current;
65 current = current->next; 75 current = current->next;
66 free (previous); 76 free (previous);
67 } 77 }
68 monitor_unlock (list->lock); 78 mu_refcount_unlock (list->refcount);
69 monitor_destroy (list->lock); 79 mu_refcount_destroy (&list->refcount);
70 free (list); 80 free (list);
71 } 81 }
72 return 0; 82 *plist = NULL;
83 }
73 } 84 }
74
75 int 85 int
76 mu_list_append (mu_list_t list, void *item) 86 mu_list_append (mu_list_t list, void *item)
77 { 87 {
...@@ -84,13 +94,13 @@ mu_list_append (mu_list_t list, void *item) ...@@ -84,13 +94,13 @@ mu_list_append (mu_list_t list, void *item)
84 if (ldata == NULL) 94 if (ldata == NULL)
85 return ENOMEM; 95 return ENOMEM;
86 ldata->item = item; 96 ldata->item = item;
87 monitor_lock (list->lock); 97 mu_refcount_lock (list->refcount);
88 ldata->next = &(list->head); 98 ldata->next = &(list->head);
89 ldata->prev = list->head.prev; 99 ldata->prev = list->head.prev;
90 last->next = ldata; 100 last->next = ldata;
91 list->head.prev = ldata; 101 list->head.prev = ldata;
92 list->count++; 102 list->count++;
93 monitor_unlock (list->lock); 103 mu_refcount_unlock (list->refcount);
94 return 0; 104 return 0;
95 } 105 }
96 106
...@@ -106,13 +116,13 @@ mu_list_prepend (mu_list_t list, void *item) ...@@ -106,13 +116,13 @@ mu_list_prepend (mu_list_t list, void *item)
106 if (ldata == NULL) 116 if (ldata == NULL)
107 return ENOMEM; 117 return ENOMEM;
108 ldata->item = item; 118 ldata->item = item;
109 monitor_lock (list->lock); 119 mu_refcount_lock (list->refcount);
110 ldata->prev = &(list->head); 120 ldata->prev = &(list->head);
111 ldata->next = list->head.next; 121 ldata->next = list->head.next;
112 first->prev = ldata; 122 first->prev = ldata;
113 list->head.next = ldata; 123 list->head.next = ldata;
114 list->count++; 124 list->count++;
115 monitor_unlock (list->lock); 125 mu_refcount_unlock (list->refcount);
116 return 0; 126 return 0;
117 } 127 }
118 128
...@@ -129,7 +139,9 @@ mu_list_count (mu_list_t list, size_t *pcount) ...@@ -129,7 +139,9 @@ mu_list_count (mu_list_t list, size_t *pcount)
129 { 139 {
130 if (list == NULL || pcount == NULL) 140 if (list == NULL || pcount == NULL)
131 return EINVAL; 141 return EINVAL;
142 mu_refcount_lock (list->refcount);
132 *pcount = list->count; 143 *pcount = list->count;
144 mu_refcount_unlock (list->refcount);
133 return 0; 145 return 0;
134 } 146 }
135 147
...@@ -140,7 +152,7 @@ mu_list_remove (mu_list_t list, void *item) ...@@ -140,7 +152,7 @@ mu_list_remove (mu_list_t list, void *item)
140 int status = ENOENT; 152 int status = ENOENT;
141 if (list == NULL) 153 if (list == NULL)
142 return EINVAL; 154 return EINVAL;
143 monitor_lock (list->lock); 155 mu_refcount_lock (list->refcount);
144 for (previous = &(list->head), current = list->head.next; 156 for (previous = &(list->head), current = list->head.next;
145 current != &(list->head); previous = current, current = current->next) 157 current != &(list->head); previous = current, current = current->next)
146 { 158 {
...@@ -154,7 +166,7 @@ mu_list_remove (mu_list_t list, void *item) ...@@ -154,7 +166,7 @@ mu_list_remove (mu_list_t list, void *item)
154 break; 166 break;
155 } 167 }
156 } 168 }
157 monitor_unlock (list->lock); 169 mu_refcount_unlock (list->refcount);
158 return ENOENT; 170 return ENOENT;
159 } 171 }
160 172
...@@ -166,7 +178,7 @@ mu_list_get (mu_list_t list, size_t index, void **pitem) ...@@ -166,7 +178,7 @@ mu_list_get (mu_list_t list, size_t index, void **pitem)
166 int status = ENOENT; 178 int status = ENOENT;
167 if (list == NULL || pitem == NULL) 179 if (list == NULL || pitem == NULL)
168 return EINVAL; 180 return EINVAL;
169 monitor_lock (list->lock); 181 mu_refcount_lock (list->refcount);
170 for (current = list->head.next, count = 0; current != &(list->head); 182 for (current = list->head.next, count = 0; current != &(list->head);
171 current = current->next, count++) 183 current = current->next, count++)
172 { 184 {
...@@ -177,13 +189,12 @@ mu_list_get (mu_list_t list, size_t index, void **pitem) ...@@ -177,13 +189,12 @@ mu_list_get (mu_list_t list, size_t index, void **pitem)
177 break; 189 break;
178 } 190 }
179 } 191 }
180 monitor_unlock (list->lock); 192 mu_refcount_unlock (list->refcount);
181 return status; 193 return status;
182 } 194 }
183 195
184 static int l_add_ref __P ((iterator_t)); 196 static int l_ref __P ((iterator_t));
185 static int l_release __P ((iterator_t)); 197 static void l_destroy __P ((iterator_t *));
186 static int l_destroy __P ((iterator_t));
187 static int l_first __P ((iterator_t)); 198 static int l_first __P ((iterator_t));
188 static int l_next __P ((iterator_t)); 199 static int l_next __P ((iterator_t));
189 static int l_current __P ((iterator_t, void *)); 200 static int l_current __P ((iterator_t, void *));
...@@ -192,8 +203,7 @@ static int l_is_done __P ((iterator_t)); ...@@ -192,8 +203,7 @@ static int l_is_done __P ((iterator_t));
192 static struct _iterator_vtable l_i_vtable = 203 static struct _iterator_vtable l_i_vtable =
193 { 204 {
194 /* Base. */ 205 /* Base. */
195 l_add_ref, 206 l_ref,
196 l_release,
197 l_destroy, 207 l_destroy,
198 208
199 l_first, 209 l_first,
...@@ -214,56 +224,39 @@ mu_list_get_iterator (mu_list_t list, iterator_t *piterator) ...@@ -214,56 +224,39 @@ mu_list_get_iterator (mu_list_t list, iterator_t *piterator)
214 if (l_iterator == NULL) 224 if (l_iterator == NULL)
215 return MU_ERROR_NO_MEMORY; 225 return MU_ERROR_NO_MEMORY;
216 226
217 l_iterator->base.vtable = &l_i_vtable; 227 mu_refcount_create (&l_iterator->refcount);
218 l_iterator->ref = 1; 228 if (l_iterator->refcount == NULL)
229 {
230 free (l_iterator);
231 return MU_ERROR_NO_MEMORY;
232 }
233 /* Incremente the reference count of the list. */
219 l_iterator->list = list; 234 l_iterator->list = list;
235 mu_list_ref (list);
220 l_iterator->current = NULL; 236 l_iterator->current = NULL;
221 monitor_create (&(l_iterator->lock)); 237 l_iterator->base.vtable = &l_i_vtable;
222 *piterator = &l_iterator->base; 238 *piterator = &l_iterator->base;
223 return 0; 239 return 0;
224 } 240 }
225 241
226 static int 242 static int
227 l_add_ref (iterator_t iterator) 243 l_ref (iterator_t iterator)
228 { 244 {
229 int status = 0;
230 struct l_iterator *l_iterator = (struct l_iterator *)iterator; 245 struct l_iterator *l_iterator = (struct l_iterator *)iterator;
231 if (l_iterator) 246 return mu_refcount_inc (l_iterator->refcount);
232 {
233 monitor_lock (l_iterator->lock);
234 status = ++l_iterator->ref;
235 monitor_unlock (l_iterator->lock);
236 }
237 return status;
238 } 247 }
239 248
240 static int 249 static void
241 l_release (iterator_t iterator) 250 l_destroy (iterator_t *piterator)
242 { 251 {
243 int status = 0; 252 struct l_iterator *l_iterator = (struct l_iterator *)*piterator;
244 struct l_iterator *l_iterator = (struct l_iterator *)iterator; 253 if (mu_refcount_dec (l_iterator->refcount) == 0)
245 if (l_iterator)
246 {
247 monitor_lock (l_iterator->lock);
248 status = --l_iterator->ref;
249 if (status <= 0)
250 { 254 {
251 monitor_unlock (l_iterator->lock); 255 /* The reference was bumped when creating the iterator. */
252 l_destroy (iterator); 256 mu_list_destroy (&l_iterator->list);
253 return 0; 257 mu_refcount_destroy (&l_iterator->refcount);
254 }
255 monitor_unlock (l_iterator->lock);
256 }
257 return status;
258 }
259
260 static int
261 l_destroy (iterator_t iterator)
262 {
263 struct l_iterator *l_iterator = (struct l_iterator *)iterator;
264 monitor_destroy (l_iterator->lock);
265 free (l_iterator); 258 free (l_iterator);
266 return 0; 259 }
267 } 260 }
268 261
269 static int 262 static int
...@@ -273,9 +266,9 @@ l_first (iterator_t iterator) ...@@ -273,9 +266,9 @@ l_first (iterator_t iterator)
273 mu_list_t list = l_iterator->list; 266 mu_list_t list = l_iterator->list;
274 if (list) 267 if (list)
275 { 268 {
276 monitor_lock (list->lock); 269 mu_refcount_lock (list->refcount);
277 l_iterator->current = l_iterator->list->head.next; 270 l_iterator->current = l_iterator->list->head.next;
278 monitor_unlock (list->lock); 271 mu_refcount_unlock (list->refcount);
279 } 272 }
280 return 0; 273 return 0;
281 } 274 }
...@@ -289,9 +282,9 @@ l_next (iterator_t iterator) ...@@ -289,9 +282,9 @@ l_next (iterator_t iterator)
289 { 282 {
290 if (l_iterator->current) 283 if (l_iterator->current)
291 { 284 {
292 monitor_lock (list->lock); 285 mu_refcount_lock (list->refcount);
293 l_iterator->current = l_iterator->current->next; 286 l_iterator->current = l_iterator->current->next;
294 monitor_unlock (list->lock); 287 mu_refcount_unlock (list->refcount);
295 } 288 }
296 else 289 else
297 l_first (iterator); 290 l_first (iterator);
...@@ -307,9 +300,9 @@ l_is_done (iterator_t iterator) ...@@ -307,9 +300,9 @@ l_is_done (iterator_t iterator)
307 mu_list_t list = l_iterator->list; 300 mu_list_t list = l_iterator->list;
308 if (list) 301 if (list)
309 { 302 {
310 monitor_lock (list->lock); 303 mu_refcount_lock (list->refcount);
311 done = (l_iterator->current == &(list->head)); 304 done = (l_iterator->current == &(list->head));
312 monitor_unlock (list->lock); 305 mu_refcount_unlock (list->refcount);
313 } 306 }
314 return done; 307 return done;
315 } 308 }
...@@ -321,12 +314,12 @@ l_current (iterator_t iterator, void *item) ...@@ -321,12 +314,12 @@ l_current (iterator_t iterator, void *item)
321 mu_list_t list = l_iterator->list; 314 mu_list_t list = l_iterator->list;
322 if (list) 315 if (list)
323 { 316 {
324 monitor_lock (list->lock); 317 mu_refcount_lock (list->refcount);
325 if (l_iterator->current) 318 if (l_iterator->current)
326 *((void **)item) = l_iterator->current->item; 319 *((void **)item) = l_iterator->current->item;
327 else 320 else
328 *((void **)item) = NULL; 321 *((void **)item) = NULL;
329 monitor_unlock (list->lock); 322 mu_refcount_unlock (list->refcount);
330 } 323 }
331 return 0; 324 return 0;
332 } 325 }
......
...@@ -24,34 +24,28 @@ ...@@ -24,34 +24,28 @@
24 #include <mailutils/sys/locker.h> 24 #include <mailutils/sys/locker.h>
25 25
26 int 26 int
27 (locker_add_ref) (locker_t locker) 27 locker_ref (locker_t locker)
28 { 28 {
29 if (locker == NULL || locker->vtable == NULL 29 if (locker == NULL || locker->vtable == NULL
30 || locker->vtable->add_ref == NULL) 30 || locker->vtable->ref == NULL)
31 return MU_ERROR_NOT_SUPPORTED; 31 return MU_ERROR_NOT_SUPPORTED;
32 return locker->vtable->add_ref (locker); 32 return locker->vtable->ref (locker);
33 } 33 }
34 34
35 int 35 void
36 (locker_release) (locker_t locker) 36 locker_destroy (locker_t *plocker)
37 { 37 {
38 if (locker == NULL || locker->vtable == NULL 38 if (plocker && *plocker)
39 || locker->vtable->release == NULL) 39 {
40 return MU_ERROR_NOT_SUPPORTED; 40 locker_t locker = *plocker;
41 return locker->vtable->release (locker); 41 if (locker->vtable && locker->vtable->destroy)
42 } 42 locker->vtable->destroy (plocker);
43 43 *plocker = NULL;
44 int 44 }
45 (locker_destroy) (locker_t locker)
46 {
47 if (locker == NULL || locker->vtable == NULL
48 || locker->vtable->destroy == NULL)
49 return MU_ERROR_NOT_SUPPORTED;
50 return locker->vtable->destroy (locker);
51 } 45 }
52 46
53 int 47 int
54 (locker_lock) (locker_t locker) 48 locker_lock (locker_t locker)
55 { 49 {
56 if (locker == NULL || locker->vtable == NULL 50 if (locker == NULL || locker->vtable == NULL
57 || locker->vtable->lock == NULL) 51 || locker->vtable->lock == NULL)
...@@ -60,7 +54,7 @@ int ...@@ -60,7 +54,7 @@ int
60 } 54 }
61 55
62 int 56 int
63 (locker_touchlock) (locker_t locker) 57 locker_touchlock (locker_t locker)
64 { 58 {
65 if (locker == NULL || locker->vtable == NULL 59 if (locker == NULL || locker->vtable == NULL
66 || locker->vtable->lock == NULL) 60 || locker->vtable->lock == NULL)
...@@ -69,7 +63,7 @@ int ...@@ -69,7 +63,7 @@ int
69 } 63 }
70 64
71 int 65 int
72 (locker_unlock) (locker_t locker) 66 locker_unlock (locker_t locker)
73 { 67 {
74 if (locker == NULL || locker->vtable == NULL 68 if (locker == NULL || locker->vtable == NULL
75 || locker->vtable->lock == NULL) 69 || locker->vtable->lock == NULL)
......
...@@ -19,30 +19,24 @@ ...@@ -19,30 +19,24 @@
19 #include <mailutils/sys/mailbox.h> 19 #include <mailutils/sys/mailbox.h>
20 20
21 int 21 int
22 mailbox_add_ref (mailbox_t mailbox) 22 mailbox_ref (mailbox_t mailbox)
23 { 23 {
24 if (mailbox == NULL || mailbox->vtable == NULL 24 if (mailbox == NULL || mailbox->vtable == NULL
25 || mailbox->vtable->add_ref == NULL) 25 || mailbox->vtable->ref == NULL)
26 return MU_ERROR_NOT_SUPPORTED; 26 return MU_ERROR_NOT_SUPPORTED;
27 return mailbox->vtable->add_ref (mailbox); 27 return mailbox->vtable->ref (mailbox);
28 } 28 }
29 29
30 int 30 void
31 mailbox_release (mailbox_t mailbox) 31 mailbox_destroy (mailbox_t *pmailbox)
32 {
33 if (mailbox == NULL || mailbox->vtable == NULL
34 || mailbox->vtable->release == NULL)
35 return MU_ERROR_NOT_SUPPORTED;
36 return mailbox->vtable->release (mailbox);
37 }
38
39 int
40 mailbox_destroy (mailbox_t mailbox)
41 { 32 {
42 if (mailbox == NULL || mailbox->vtable == NULL 33 if (pmailbox && *pmailbox)
43 || mailbox->vtable->destroy == NULL) 34 {
44 return MU_ERROR_NOT_SUPPORTED; 35 mailbox_t mailbox = *pmailbox;
45 return mailbox->vtable->destroy (mailbox); 36 if (mailbox->vtable && mailbox->vtable->destroy)
37 mailbox->vtable->destroy (pmailbox);
38 *pmailbox = NULL;
39 }
46 } 40 }
47 41
48 int 42 int
...@@ -182,7 +176,6 @@ mailbox_scan (mailbox_t mailbox, size_t no, size_t *count) ...@@ -182,7 +176,6 @@ mailbox_scan (mailbox_t mailbox, size_t no, size_t *count)
182 return mailbox->vtable->scan (mailbox, no, count); 176 return mailbox->vtable->scan (mailbox, no, count);
183 } 177 }
184 178
185
186 /* Mailbox Stream. */ 179 /* Mailbox Stream. */
187 int 180 int
188 mailbox_get_stream (mailbox_t mailbox, stream_t *stream) 181 mailbox_get_stream (mailbox_t mailbox, stream_t *stream)
...@@ -193,7 +186,6 @@ mailbox_get_stream (mailbox_t mailbox, stream_t *stream) ...@@ -193,7 +186,6 @@ mailbox_get_stream (mailbox_t mailbox, stream_t *stream)
193 return mailbox->vtable->get_stream (mailbox, stream); 186 return mailbox->vtable->get_stream (mailbox, stream);
194 } 187 }
195 188
196
197 /* Authentication. */ 189 /* Authentication. */
198 int 190 int
199 mailbox_get_authority (mailbox_t mailbox, authority_t *authority) 191 mailbox_get_authority (mailbox_t mailbox, authority_t *authority)
...@@ -223,7 +215,6 @@ mailbox_get_property (mailbox_t mailbox, property_t *property) ...@@ -223,7 +215,6 @@ mailbox_get_property (mailbox_t mailbox, property_t *property)
223 return mailbox->vtable->get_property (mailbox, property); 215 return mailbox->vtable->get_property (mailbox, property);
224 } 216 }
225 217
226
227 /* URL. */ 218 /* URL. */
228 int 219 int
229 mailbox_get_url (mailbox_t mailbox, url_t *url) 220 mailbox_get_url (mailbox_t mailbox, url_t *url)
...@@ -234,7 +225,6 @@ mailbox_get_url (mailbox_t mailbox, url_t *url) ...@@ -234,7 +225,6 @@ mailbox_get_url (mailbox_t mailbox, url_t *url)
234 return mailbox->vtable->get_url (mailbox, url); 225 return mailbox->vtable->get_url (mailbox, url);
235 } 226 }
236 227
237
238 /* For any debuging */ 228 /* For any debuging */
239 int 229 int
240 mailbox_get_debug (mailbox_t mailbox, mu_debug_t *debug) 230 mailbox_get_debug (mailbox_t mailbox, mu_debug_t *debug)
...@@ -254,7 +244,6 @@ mailbox_set_debug (mailbox_t mailbox, mu_debug_t debug) ...@@ -254,7 +244,6 @@ mailbox_set_debug (mailbox_t mailbox, mu_debug_t debug)
254 return mailbox->vtable->set_debug (mailbox, debug); 244 return mailbox->vtable->set_debug (mailbox, debug);
255 } 245 }
256 246
257
258 /* Events. */ 247 /* Events. */
259 int 248 int
260 mailbox_get_observable (mailbox_t mailbox, observable_t *observable) 249 mailbox_get_observable (mailbox_t mailbox, observable_t *observable)
......
...@@ -40,48 +40,29 @@ ...@@ -40,48 +40,29 @@
40 #endif 40 #endif
41 41
42 static int 42 static int
43 _map_add_ref (stream_t stream) 43 _map_ref (stream_t stream)
44 { 44 {
45 int status;
46 struct _ms *ms = (struct _ms *)stream; 45 struct _ms *ms = (struct _ms *)stream;
47 monitor_lock (ms->lock); 46 return mu_refcount_inc (ms->refcount);
48 status = ++ms->ref;
49 monitor_unlock (ms->lock);
50 return status;
51 } 47 }
52 48
53 static int 49 static void
54 _map_destroy (stream_t stream) 50 _map_destroy (stream_t *pstream)
55 { 51 {
56 struct _ms *ms = (struct _ms *)stream; 52 struct _ms *ms = (struct _ms *)*pstream;
57 53
54 if (mu_refcount_dec (ms->refcount) == 0)
55 {
58 if (ms->ptr != MAP_FAILED) 56 if (ms->ptr != MAP_FAILED)
59 { 57 {
60 if (ms->ptr) 58 if (ms->ptr)
61 munmap (ms->ptr, ms->size); 59 munmap (ms->ptr, ms->size);
60 }
62 if (ms->fd != -1) 61 if (ms->fd != -1)
63 close (ms->fd); 62 close (ms->fd);
64 monitor_destroy (ms->lock); 63 mu_refcount_destroy (&ms->refcount);
65 }
66 free (ms); 64 free (ms);
67 return 0;
68 }
69
70 static int
71 _map_release (stream_t stream)
72 {
73 int status;
74 struct _ms *ms = (struct _ms *)stream;
75 monitor_lock (ms->lock);
76 status = --ms->ref;
77 if (status <= 0)
78 {
79 monitor_unlock (ms->lock);
80 _map_destroy (stream);
81 return 0;
82 } 65 }
83 monitor_unlock (ms->lock);
84 return status;
85 } 66 }
86 67
87 static int 68 static int
...@@ -90,7 +71,7 @@ _map_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) ...@@ -90,7 +71,7 @@ _map_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
90 struct _ms *ms = (struct _ms *)stream; 71 struct _ms *ms = (struct _ms *)stream;
91 size_t n = 0; 72 size_t n = 0;
92 73
93 monitor_lock (ms->lock); 74 mu_refcount_lock (ms->refcount);
94 if (ms->ptr != MAP_FAILED && ms->ptr) 75 if (ms->ptr != MAP_FAILED && ms->ptr)
95 { 76 {
96 if (ms->offset < (off_t)ms->size) 77 if (ms->offset < (off_t)ms->size)
...@@ -101,7 +82,7 @@ _map_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) ...@@ -101,7 +82,7 @@ _map_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
101 ms->offset += n; 82 ms->offset += n;
102 } 83 }
103 } 84 }
104 monitor_unlock (ms->lock); 85 mu_refcount_unlock (ms->refcount);
105 86
106 if (nbytes) 87 if (nbytes)
107 *nbytes = n; 88 *nbytes = n;
...@@ -114,7 +95,7 @@ _map_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) ...@@ -114,7 +95,7 @@ _map_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
114 struct _ms *ms = (struct _ms *)stream; 95 struct _ms *ms = (struct _ms *)stream;
115 size_t n = 0; 96 size_t n = 0;
116 97
117 monitor_lock (ms->lock); 98 mu_refcount_lock (ms->refcount);
118 if (ms->ptr != MAP_FAILED && ms->ptr) 99 if (ms->ptr != MAP_FAILED && ms->ptr)
119 { 100 {
120 if (ms->offset < (off_t)ms->size) 101 if (ms->offset < (off_t)ms->size)
...@@ -130,7 +111,7 @@ _map_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) ...@@ -130,7 +111,7 @@ _map_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
130 ms->offset += n; 111 ms->offset += n;
131 } 112 }
132 } 113 }
133 monitor_unlock (ms->lock); 114 mu_refcount_unlock (ms->refcount);
134 115
135 if (nbytes) 116 if (nbytes)
136 *nbytes = n; 117 *nbytes = n;
...@@ -144,7 +125,7 @@ _map_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) ...@@ -144,7 +125,7 @@ _map_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
144 int err = 0; 125 int err = 0;
145 size_t n = 0; 126 size_t n = 0;
146 127
147 monitor_lock (ms->lock); 128 mu_refcount_lock (ms->refcount);
148 if (ms->mflags & PROT_WRITE) 129 if (ms->mflags & PROT_WRITE)
149 { 130 {
150 /* Bigger we have to remmap. */ 131 /* Bigger we have to remmap. */
...@@ -175,7 +156,8 @@ _map_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) ...@@ -175,7 +156,8 @@ _map_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
175 } 156 }
176 else 157 else
177 err = MU_ERROR_IO; 158 err = MU_ERROR_IO;
178 monitor_unlock (ms->lock); 159
160 mu_refcount_lock (ms->refcount);
179 161
180 if (nbytes) 162 if (nbytes)
181 *nbytes = n; 163 *nbytes = n;
...@@ -188,7 +170,7 @@ _map_truncate (stream_t stream, off_t len) ...@@ -188,7 +170,7 @@ _map_truncate (stream_t stream, off_t len)
188 struct _ms *ms = (struct _ms *)stream; 170 struct _ms *ms = (struct _ms *)stream;
189 int err = 0; 171 int err = 0;
190 172
191 monitor_lock (ms->lock); 173 mu_refcount_lock (ms->refcount);
192 if (ms->ptr != MAP_FAILED) 174 if (ms->ptr != MAP_FAILED)
193 { 175 {
194 /* Remap. */ 176 /* Remap. */
...@@ -209,7 +191,7 @@ _map_truncate (stream_t stream, off_t len) ...@@ -209,7 +191,7 @@ _map_truncate (stream_t stream, off_t len)
209 err = errno; 191 err = errno;
210 } 192 }
211 } 193 }
212 monitor_unlock (ms->lock); 194 mu_refcount_unlock (ms->refcount);
213 return err; 195 return err;
214 } 196 }
215 197
...@@ -220,7 +202,7 @@ _map_get_size (stream_t stream, off_t *psize) ...@@ -220,7 +202,7 @@ _map_get_size (stream_t stream, off_t *psize)
220 struct stat stbuf; 202 struct stat stbuf;
221 int err = 0; 203 int err = 0;
222 204
223 monitor_lock (ms->lock); 205 mu_refcount_lock (ms->refcount);
224 stbuf.st_size = 0; 206 stbuf.st_size = 0;
225 if (ms->ptr != MAP_FAILED) 207 if (ms->ptr != MAP_FAILED)
226 { 208 {
...@@ -251,7 +233,7 @@ _map_get_size (stream_t stream, off_t *psize) ...@@ -251,7 +233,7 @@ _map_get_size (stream_t stream, off_t *psize)
251 } 233 }
252 } 234 }
253 } 235 }
254 monitor_unlock (ms->lock); 236 mu_refcount_unlock (ms->refcount);
255 if (psize) 237 if (psize)
256 *psize = stbuf.st_size; 238 *psize = stbuf.st_size;
257 return err; 239 return err;
...@@ -262,10 +244,10 @@ _map_flush (stream_t stream) ...@@ -262,10 +244,10 @@ _map_flush (stream_t stream)
262 { 244 {
263 int err = 0; 245 int err = 0;
264 struct _ms *ms = (struct _ms *)stream; 246 struct _ms *ms = (struct _ms *)stream;
265 monitor_lock (ms->lock); 247 mu_refcount_lock (ms->refcount);
266 if (ms->ptr != MAP_FAILED && ms->ptr != NULL) 248 if (ms->ptr != MAP_FAILED && ms->ptr != NULL)
267 err = msync (ms->ptr, ms->size, MS_SYNC); 249 err = msync (ms->ptr, ms->size, MS_SYNC);
268 monitor_unlock (ms->lock); 250 mu_refcount_unlock (ms->refcount);
269 return 0; 251 return 0;
270 } 252 }
271 253
...@@ -338,7 +320,7 @@ _map_close (stream_t stream) ...@@ -338,7 +320,7 @@ _map_close (stream_t stream)
338 { 320 {
339 struct _ms *ms = (struct _ms *)stream; 321 struct _ms *ms = (struct _ms *)stream;
340 int err = 0; 322 int err = 0;
341 monitor_lock (ms->lock); 323 mu_refcount_lock (ms->refcount);
342 if (ms->ptr != MAP_FAILED) 324 if (ms->ptr != MAP_FAILED)
343 { 325 {
344 if (ms->ptr && munmap (ms->ptr, ms->size) != 0) 326 if (ms->ptr && munmap (ms->ptr, ms->size) != 0)
...@@ -349,7 +331,7 @@ _map_close (stream_t stream) ...@@ -349,7 +331,7 @@ _map_close (stream_t stream)
349 if (close (ms->fd) != 0) 331 if (close (ms->fd) != 0)
350 err = errno; 332 err = errno;
351 ms->fd = -1; 333 ms->fd = -1;
352 monitor_unlock (ms->lock); 334 mu_refcount_unlock (ms->refcount);
353 return err; 335 return err;
354 } 336 }
355 337
...@@ -455,8 +437,7 @@ _map_open (stream_t stream, const char *filename, int port, int flags) ...@@ -455,8 +437,7 @@ _map_open (stream_t stream, const char *filename, int port, int flags)
455 437
456 static struct _stream_vtable _map_vtable = 438 static struct _stream_vtable _map_vtable =
457 { 439 {
458 _map_add_ref, 440 _map_ref,
459 _map_release,
460 _map_destroy, 441 _map_destroy,
461 442
462 _map_open, 443 _map_open,
...@@ -501,13 +482,17 @@ stream_mapfile_create (stream_t *pstream) ...@@ -501,13 +482,17 @@ stream_mapfile_create (stream_t *pstream)
501 if (ms == NULL) 482 if (ms == NULL)
502 return MU_ERROR_NO_MEMORY; 483 return MU_ERROR_NO_MEMORY;
503 484
504 ms->base.vtable = &_map_vtable; 485 mu_refcount_create (&ms->refcount);
505 ms->ref = 1; 486 if (ms->refcount == NULL)
487 {
488 free (ms);
489 return MU_ERROR_NO_MEMORY;
490 }
506 ms->fd = -1; 491 ms->fd = -1;
507 ms->offset = -1; 492 ms->offset = -1;
508 ms->flags = 0; 493 ms->flags = 0;
509 ms->mflags = 0; 494 ms->mflags = 0;
510 monitor_create (&(ms->lock)); 495 ms->base.vtable = &_map_vtable;
511 *pstream = &ms->base; 496 *pstream = &ms->base;
512 497
513 return 0; 498 return 0;
......
...@@ -27,41 +27,23 @@ ...@@ -27,41 +27,23 @@
27 #include <mailutils/sys/memstream.h> 27 #include <mailutils/sys/memstream.h>
28 28
29 static int 29 static int
30 _memory_add_ref (stream_t stream) 30 _memory_ref (stream_t stream)
31 { 31 {
32 int status;
33 struct _memory_stream *mem = (struct _memory_stream *)stream; 32 struct _memory_stream *mem = (struct _memory_stream *)stream;
34 monitor_lock (mem->lock); 33 return mu_refcount_inc (mem->refcount);
35 status = ++mem->ref;
36 monitor_unlock (mem->lock);
37 return status;
38 } 34 }
39 35
40 static int 36 static void
41 _memory_destroy (stream_t stream) 37 _memory_destroy (stream_t *pstream)
42 { 38 {
43 struct _memory_stream *mem = (struct _memory_stream *)stream; 39 struct _memory_stream *mem = (struct _memory_stream *)*pstream;
40 if (mu_refcount_dec (mem->refcount) == 0)
41 {
44 if (mem && mem->ptr != NULL) 42 if (mem && mem->ptr != NULL)
45 free (mem->ptr); 43 free (mem->ptr);
44 mu_refcount_destroy (&mem->refcount);
46 free (mem); 45 free (mem);
47 return 0;
48 }
49
50 static int
51 _memory_release (stream_t stream)
52 {
53 int status;
54 struct _memory_stream *mem = (struct _memory_stream *)stream;
55 monitor_lock (mem->lock);
56 status = --mem->ref;
57 if (status <= 0)
58 {
59 monitor_unlock (mem->lock);
60 _memory_destroy (stream);
61 return 0;
62 } 46 }
63 monitor_unlock (mem->lock);
64 return status;
65 } 47 }
66 48
67 static int 49 static int
...@@ -69,6 +51,8 @@ _memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) ...@@ -69,6 +51,8 @@ _memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
69 { 51 {
70 struct _memory_stream *mem = (struct _memory_stream *)stream; 52 struct _memory_stream *mem = (struct _memory_stream *)stream;
71 size_t n = 0; 53 size_t n = 0;
54
55 mu_refcount_lock (mem->refcount);
72 if (mem->ptr != NULL && (mem->offset < (off_t)mem->size)) 56 if (mem->ptr != NULL && (mem->offset < (off_t)mem->size))
73 { 57 {
74 n = ((mem->offset + osize) > mem->size) ? 58 n = ((mem->offset + osize) > mem->size) ?
...@@ -76,6 +60,7 @@ _memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes) ...@@ -76,6 +60,7 @@ _memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
76 memcpy (optr, mem->ptr + mem->offset, n); 60 memcpy (optr, mem->ptr + mem->offset, n);
77 mem->offset += n; 61 mem->offset += n;
78 } 62 }
63 mu_refcount_unlock (mem->refcount);
79 if (nbytes) 64 if (nbytes)
80 *nbytes = n; 65 *nbytes = n;
81 return 0; 66 return 0;
...@@ -87,6 +72,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) ...@@ -87,6 +72,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
87 struct _memory_stream *mem = (struct _memory_stream *)stream; 72 struct _memory_stream *mem = (struct _memory_stream *)stream;
88 char *nl; 73 char *nl;
89 size_t n = 0; 74 size_t n = 0;
75 mu_refcount_lock (mem->refcount);
90 if (mem->ptr && (mem->offset < (off_t)mem->size)) 76 if (mem->ptr && (mem->offset < (off_t)mem->size))
91 { 77 {
92 /* Save space for the null byte. */ 78 /* Save space for the null byte. */
...@@ -98,6 +84,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes) ...@@ -98,6 +84,7 @@ _memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
98 optr[n] = '\0'; 84 optr[n] = '\0';
99 mem->offset += n; 85 mem->offset += n;
100 } 86 }
87 mu_refcount_unlock (mem->refcount);
101 if (nbytes) 88 if (nbytes)
102 *nbytes = n; 89 *nbytes = n;
103 return 0; 90 return 0;
...@@ -108,6 +95,7 @@ _memory_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) ...@@ -108,6 +95,7 @@ _memory_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
108 { 95 {
109 struct _memory_stream *mem = (struct _memory_stream *)stream; 96 struct _memory_stream *mem = (struct _memory_stream *)stream;
110 97
98 mu_refcount_lock (mem->refcount);
111 /* Bigger we have to realloc. */ 99 /* Bigger we have to realloc. */
112 if (mem->size < (mem->offset + isize)) 100 if (mem->size < (mem->offset + isize))
113 { 101 {
...@@ -120,6 +108,7 @@ _memory_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes) ...@@ -120,6 +108,7 @@ _memory_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
120 108
121 memcpy (mem->ptr + mem->offset, iptr, isize); 109 memcpy (mem->ptr + mem->offset, iptr, isize);
122 mem->offset += isize; 110 mem->offset += isize;
111 mu_refcount_unlock (mem->refcount);
123 if (nbytes) 112 if (nbytes)
124 *nbytes = isize; 113 *nbytes = isize;
125 return 0; 114 return 0;
...@@ -130,6 +119,7 @@ _memory_truncate (stream_t stream, off_t len) ...@@ -130,6 +119,7 @@ _memory_truncate (stream_t stream, off_t len)
130 { 119 {
131 struct _memory_stream *mem = (struct _memory_stream *)stream; 120 struct _memory_stream *mem = (struct _memory_stream *)stream;
132 121
122 mu_refcount_lock (mem->refcount);
133 if (len == 0) 123 if (len == 0)
134 { 124 {
135 free (mem->ptr); 125 free (mem->ptr);
...@@ -144,6 +134,7 @@ _memory_truncate (stream_t stream, off_t len) ...@@ -144,6 +134,7 @@ _memory_truncate (stream_t stream, off_t len)
144 } 134 }
145 mem->size = len; 135 mem->size = len;
146 mem->offset = len; 136 mem->offset = len;
137 mu_refcount_unlock (mem->refcount);
147 return 0; 138 return 0;
148 } 139 }
149 140
...@@ -151,8 +142,10 @@ static int ...@@ -151,8 +142,10 @@ static int
151 _memory_get_size (stream_t stream, off_t *psize) 142 _memory_get_size (stream_t stream, off_t *psize)
152 { 143 {
153 struct _memory_stream *mem = (struct _memory_stream *)stream; 144 struct _memory_stream *mem = (struct _memory_stream *)stream;
145 mu_refcount_lock (mem->refcount);
154 if (psize) 146 if (psize)
155 *psize = mem->size; 147 *psize = mem->size;
148 mu_refcount_unlock (mem->refcount);
156 return 0; 149 return 0;
157 } 150 }
158 151
...@@ -160,11 +153,13 @@ static int ...@@ -160,11 +153,13 @@ static int
160 _memory_close (stream_t stream) 153 _memory_close (stream_t stream)
161 { 154 {
162 struct _memory_stream *mem = (struct _memory_stream *)stream; 155 struct _memory_stream *mem = (struct _memory_stream *)stream;
156 mu_refcount_lock (mem->refcount);
163 if (mem->ptr) 157 if (mem->ptr)
164 free (mem->ptr); 158 free (mem->ptr);
165 mem->ptr = NULL; 159 mem->ptr = NULL;
166 mem->size = 0; 160 mem->size = 0;
167 mem->offset = 0; 161 mem->offset = 0;
162 mu_refcount_unlock (mem->refcount);
168 return 0; 163 return 0;
169 } 164 }
170 165
...@@ -278,6 +273,7 @@ _memory_open (stream_t stream, const char *filename, int port, int flags) ...@@ -278,6 +273,7 @@ _memory_open (stream_t stream, const char *filename, int port, int flags)
278 (void)filename; /* Ignored. */ 273 (void)filename; /* Ignored. */
279 (void)flags; /* Ignored. */ 274 (void)flags; /* Ignored. */
280 275
276 mu_refcount_lock (mem->refcount);
281 /* Close any previous file. */ 277 /* Close any previous file. */
282 if (mem->ptr) 278 if (mem->ptr)
283 free (mem->ptr); 279 free (mem->ptr);
...@@ -285,13 +281,13 @@ _memory_open (stream_t stream, const char *filename, int port, int flags) ...@@ -285,13 +281,13 @@ _memory_open (stream_t stream, const char *filename, int port, int flags)
285 mem->size = 0; 281 mem->size = 0;
286 mem->offset = 0; 282 mem->offset = 0;
287 mem->flags = flags; 283 mem->flags = flags;
284 mu_refcount_unlock (mem->refcount);
288 return 0; 285 return 0;
289 } 286 }
290 287
291 static struct _stream_vtable _mem_vtable = 288 static struct _stream_vtable _mem_vtable =
292 { 289 {
293 _memory_add_ref, 290 _memory_ref,
294 _memory_release,
295 _memory_destroy, 291 _memory_destroy,
296 292
297 _memory_open, 293 _memory_open,
...@@ -331,14 +327,17 @@ stream_memory_create (stream_t *pstream) ...@@ -331,14 +327,17 @@ stream_memory_create (stream_t *pstream)
331 if (mem == NULL) 327 if (mem == NULL)
332 return MU_ERROR_NO_MEMORY; 328 return MU_ERROR_NO_MEMORY;
333 329
334 mem->base.vtable = &_mem_vtable; 330 mu_refcount_create (&mem->refcount);
335 mem->ref = 1; 331 if (mem->refcount == NULL)
332 {
333 free (mem);
334 return MU_ERROR_NO_MEMORY;
335 }
336 mem->ptr = NULL; 336 mem->ptr = NULL;
337 mem->size = 0; 337 mem->size = 0;
338 mem->offset = 0; 338 mem->offset = 0;
339 mem->flags = 0; 339 mem->flags = 0;
340 monitor_create (&(mem->lock)); 340 mem->base.vtable = &_mem_vtable;
341 *pstream = &mem->base; 341 *pstream = &mem->base;
342
343 return 0; 342 return 0;
344 } 343 }
......
...@@ -24,30 +24,24 @@ ...@@ -24,30 +24,24 @@
24 #include <mailutils/sys/message.h> 24 #include <mailutils/sys/message.h>
25 25
26 int 26 int
27 message_add_ref (message_t msg) 27 message_ref (message_t msg)
28 { 28 {
29 if (msg == NULL || msg->vtable == NULL 29 if (msg == NULL || msg->vtable == NULL
30 || msg->vtable->add_ref == NULL) 30 || msg->vtable->ref == NULL)
31 return MU_ERROR_NOT_SUPPORTED; 31 return MU_ERROR_NOT_SUPPORTED;
32 return msg->vtable->add_ref (msg); 32 return msg->vtable->ref (msg);
33 } 33 }
34 34
35 int 35 void
36 message_release (message_t msg) 36 message_destroy (message_t *pmsg)
37 { 37 {
38 if (msg == NULL || msg->vtable == NULL 38 if (pmsg && *pmsg)
39 || msg->vtable->release == NULL) 39 {
40 return MU_ERROR_NOT_SUPPORTED; 40 message_t msg = *pmsg;
41 return msg->vtable->release (msg); 41 if (msg->vtable && msg->vtable->destroy)
42 } 42 msg->vtable->destroy (pmsg);
43 43 *pmsg = NULL;
44 int 44 }
45 message_destroy (message_t msg)
46 {
47 if (msg == NULL || msg->vtable == NULL
48 || msg->vtable->destroy == NULL)
49 return MU_ERROR_NOT_SUPPORTED;
50 return msg->vtable->destroy (msg);
51 } 45 }
52 46
53 int 47 int
......
...@@ -329,14 +329,14 @@ util_cpystr (char *dst, const char *src, size_t size) ...@@ -329,14 +329,14 @@ util_cpystr (char *dst, const char *src, size_t size)
329 return len; 329 return len;
330 } 330 }
331 331
332 static list_t _app_getpwnam = NULL; 332 static mu_list_t _app_getpwnam = NULL;
333 333
334 void 334 void
335 mu_register_getpwnam (struct passwd *(*fun) __P((const char *))) 335 mu_register_getpwnam (struct passwd *(*fun) __P((const char *)))
336 { 336 {
337 if (!_app_getpwnam && list_create (&_app_getpwnam)) 337 if (!_app_getpwnam && mu_list_create (&_app_getpwnam))
338 return; 338 return;
339 list_append (_app_getpwnam, fun); 339 mu_list_append (_app_getpwnam, fun);
340 } 340 }
341 341
342 struct passwd * 342 struct passwd *
...@@ -347,7 +347,7 @@ mu_getpwnam (const char *name) ...@@ -347,7 +347,7 @@ mu_getpwnam (const char *name)
347 347
348 p = getpwnam (name); 348 p = getpwnam (name);
349 349
350 if (!p && iterator_create (&itr, _app_getpwnam) == 0) 350 if (p && mu_list_get_iterator (_app_getpwnam, &itr) == 0)
351 { 351 {
352 struct passwd *(*fun) __P((const char *)); 352 struct passwd *(*fun) __P((const char *));
353 for (iterator_first (itr); !p && !iterator_is_done (itr); 353 for (iterator_first (itr); !p && !iterator_is_done (itr);
...@@ -356,7 +356,6 @@ mu_getpwnam (const char *name) ...@@ -356,7 +356,6 @@ mu_getpwnam (const char *name)
356 iterator_current (itr, (void **)&fun); 356 iterator_current (itr, (void **)&fun);
357 p = (*fun) (name); 357 p = (*fun) (name);
358 } 358 }
359
360 iterator_destroy (&itr); 359 iterator_destroy (&itr);
361 } 360 }
362 return p; 361 return p;
......
...@@ -51,18 +51,12 @@ observable_create (observable_t *pobservable) ...@@ -51,18 +51,12 @@ observable_create (observable_t *pobservable)
51 return 0; 51 return 0;
52 } 52 }
53 53
54 int 54 void
55 observable_release (observable_t observable) 55 observable_destroy (observable_t *pobservable)
56 {
57 (void)observable;
58 return 1;
59 }
60
61 int
62 observable_destroy (observable_t observable)
63 { 56 {
64 if (observable) 57 if (pobservable && *pobservable)
65 { 58 {
59 observable_t observable = *pobservable;
66 iterator_t iterator = NULL; 60 iterator_t iterator = NULL;
67 int status = mu_list_get_iterator (observable->list, &iterator); 61 int status = mu_list_get_iterator (observable->list, &iterator);
68 if (status == 0) 62 if (status == 0)
...@@ -75,16 +69,16 @@ observable_destroy (observable_t observable) ...@@ -75,16 +69,16 @@ observable_destroy (observable_t observable)
75 iterator_current (iterator, (void **)&info); 69 iterator_current (iterator, (void **)&info);
76 if (info) 70 if (info)
77 { 71 {
78 observer_release (info->observer); 72 observer_destroy (&info->observer);
79 free (info); 73 free (info);
80 } 74 }
81 } 75 }
82 iterator_release (iterator); 76 iterator_destroy (&iterator);
83 } 77 }
84 mu_list_destroy (observable->list); 78 mu_list_destroy (&observable->list);
85 free (observable); 79 free (observable);
80 *pobservable = NULL;
86 } 81 }
87 return 0;
88 } 82 }
89 83
90 int 84 int
...@@ -124,7 +118,7 @@ observable_detach (observable_t observable, observer_t observer) ...@@ -124,7 +118,7 @@ observable_detach (observable_t observable, observer_t observer)
124 break; 118 break;
125 } 119 }
126 } 120 }
127 iterator_release (iterator); 121 iterator_destroy (&iterator);
128 if (found) 122 if (found)
129 { 123 {
130 status = mu_list_remove (observable->list, info); 124 status = mu_list_remove (observable->list, info);
...@@ -155,6 +149,6 @@ observable_notify_all (observable_t observable, struct event evt) ...@@ -155,6 +149,6 @@ observable_notify_all (observable_t observable, struct event evt)
155 status |= observer_action (info->observer, evt); 149 status |= observer_action (info->observer, evt);
156 } 150 }
157 } 151 }
158 iterator_release (iterator); 152 iterator_destroy (&iterator);
159 return status; 153 return status;
160 } 154 }
......
...@@ -25,34 +25,28 @@ ...@@ -25,34 +25,28 @@
25 #include <mailutils/sys/observer.h> 25 #include <mailutils/sys/observer.h>
26 26
27 int 27 int
28 (observer_add_ref) (observer_t observer) 28 observer_ref (observer_t observer)
29 { 29 {
30 if (observer == NULL || observer->vtable == NULL 30 if (observer == NULL || observer->vtable == NULL
31 || observer->vtable->add_ref == NULL) 31 || observer->vtable->ref == NULL)
32 return MU_ERROR_NOT_SUPPORTED; 32 return MU_ERROR_NOT_SUPPORTED;
33 return observer->vtable->add_ref (observer); 33 return observer->vtable->ref (observer);
34 } 34 }
35 35
36 int 36 void
37 (observer_release) (observer_t observer) 37 observer_destroy (observer_t *pobserver)
38 {
39 if (observer == NULL || observer->vtable == NULL
40 || observer->vtable->release == NULL)
41 return MU_ERROR_NOT_SUPPORTED;
42 return observer->vtable->release (observer);
43 }
44
45 int
46 (observer_destroy) (observer_t observer)
47 { 38 {
48 if (observer == NULL || observer->vtable == NULL 39 if (pobserver && *pobserver)
49 || observer->vtable->destroy == NULL) 40 {
50 return MU_ERROR_NOT_SUPPORTED; 41 observer_t observer = *pobserver;
51 return observer->vtable->destroy (observer); 42 if (observer->vtable || observer->vtable->destroy)
43 observer->vtable->destroy (pobserver);
44 *pobserver = NULL;
45 }
52 } 46 }
53 47
54 int 48 int
55 (observer_action) (observer_t observer, struct event evt) 49 observer_action (observer_t observer, struct event evt)
56 { 50 {
57 if (observer == NULL || observer->vtable == NULL 51 if (observer == NULL || observer->vtable == NULL
58 || observer->vtable->action == NULL) 52 || observer->vtable->action == NULL)
...@@ -63,39 +57,21 @@ int ...@@ -63,39 +57,21 @@ int
63 57
64 58
65 static int 59 static int
66 _dobserver_add_ref (observer_t observer) 60 _dobserver_ref (observer_t observer)
67 { 61 {
68 struct _dobserver *dobserver = (struct _dobserver *)observer; 62 struct _dobserver *dobserver = (struct _dobserver *)observer;
69 int status; 63 return mu_refcount_inc (dobserver->refcount);
70 monitor_lock (dobserver->lock);
71 status = ++dobserver->ref;
72 monitor_unlock (dobserver->lock);
73 return status;
74 } 64 }
75 65
76 static int 66 static void
77 _dobserver_destroy (observer_t observer) 67 _dobserver_destroy (observer_t *pobserver)
78 { 68 {
79 struct _dobserver *dobserver = (struct _dobserver *)observer; 69 struct _dobserver *dobserver = (struct _dobserver *)*pobserver;
80 monitor_destroy (dobserver->lock); 70 if (mu_refcount_dec (dobserver->refcount) == 0)
81 free (dobserver);
82 return 0;
83 }
84
85 static int
86 _dobserver_release (observer_t observer)
87 {
88 int status;
89 struct _dobserver *dobserver = (struct _dobserver *)observer;
90 monitor_lock (dobserver->lock);
91 status = --dobserver->ref;
92 if (status <= 0)
93 { 71 {
94 monitor_unlock (dobserver->lock); 72 mu_refcount_destroy (&dobserver->refcount);
95 return _dobserver_destroy (observer); 73 free (dobserver);
96 } 74 }
97 monitor_unlock (dobserver->lock);
98 return status;
99 } 75 }
100 76
101 static int 77 static int
...@@ -109,8 +85,7 @@ _dobserver_action (observer_t observer, struct event evt) ...@@ -109,8 +85,7 @@ _dobserver_action (observer_t observer, struct event evt)
109 85
110 static struct _observer_vtable _dobserver_vtable = 86 static struct _observer_vtable _dobserver_vtable =
111 { 87 {
112 _dobserver_add_ref, 88 _dobserver_ref,
113 _dobserver_release,
114 _dobserver_destroy, 89 _dobserver_destroy,
115 90
116 _dobserver_action 91 _dobserver_action
...@@ -130,11 +105,15 @@ observer_create (observer_t *pobserver, ...@@ -130,11 +105,15 @@ observer_create (observer_t *pobserver,
130 if (dobserver) 105 if (dobserver)
131 return MU_ERROR_NO_MEMORY; 106 return MU_ERROR_NO_MEMORY;
132 107
133 dobserver->base.vtable = &_dobserver_vtable; 108 mu_refcount_create (&dobserver->refcount);
134 dobserver->ref = 1; 109 if (dobserver->refcount == NULL)
110 {
111 free (dobserver);
112 return MU_ERROR_NO_MEMORY;
113 }
135 dobserver->arg = arg; 114 dobserver->arg = arg;
136 dobserver->action = action; 115 dobserver->action = action;
137 monitor_create (&(dobserver->lock)); 116 dobserver->base.vtable = &_dobserver_vtable;
138 *pobserver = &dobserver->base; 117 *pobserver = &dobserver->base;
139 return 0; 118 return 0;
140 } 119 }
......
...@@ -671,7 +671,7 @@ int parse822_address_list(address_t* a, const char* s) ...@@ -671,7 +671,7 @@ int parse822_address_list(address_t* a, const char* s)
671 } 671 }
672 672
673 if(rc) { 673 if(rc) {
674 address_destroy(*a); 674 address_destroy(a);
675 } 675 }
676 676
677 return rc; 677 return rc;
...@@ -754,7 +754,7 @@ int parse822_group(const char** p, const char* e, address_t* a) ...@@ -754,7 +754,7 @@ int parse822_group(const char** p, const char* e, address_t* a)
754 if(rc || (rc = parse822_special(p, e, ';'))) { 754 if(rc || (rc = parse822_special(p, e, ';'))) {
755 *p = save; 755 *p = save;
756 756
757 address_destroy(*asave); 757 address_destroy(asave);
758 } 758 }
759 759
760 return rc; 760 return rc;
...@@ -785,7 +785,7 @@ int parse822_mail_box(const char** p, const char* e, address_t* a) ...@@ -785,7 +785,7 @@ int parse822_mail_box(const char** p, const char* e, address_t* a)
785 } 785 }
786 /* but if something else is wrong, destroy the address */ 786 /* but if something else is wrong, destroy the address */
787 if(rc) { 787 if(rc) {
788 address_destroy(*a); 788 address_destroy(a);
789 *p = save; 789 *p = save;
790 } 790 }
791 791
...@@ -854,7 +854,7 @@ int parse822_route_addr(const char** p, const char* e, address_t* a) ...@@ -854,7 +854,7 @@ int parse822_route_addr(const char** p, const char* e, address_t* a)
854 if((rc = parse822_special(p, e, '>'))) { 854 if((rc = parse822_special(p, e, '>'))) {
855 *p = save; 855 *p = save;
856 856
857 address_destroy(*a); 857 address_destroy(a);
858 858
859 return rc; 859 return rc;
860 } 860 }
......
...@@ -37,7 +37,7 @@ pop3_set_carrier (pop3_t pop3, stream_t carrier) ...@@ -37,7 +37,7 @@ pop3_set_carrier (pop3_t pop3, stream_t carrier)
37 if (pop3->carrier) 37 if (pop3->carrier)
38 { 38 {
39 stream_close (pop3->carrier); 39 stream_close (pop3->carrier);
40 stream_release (pop3->carrier); 40 stream_destroy (&pop3->carrier);
41 } 41 }
42 pop3->carrier = carrier; 42 pop3->carrier = carrier;
43 return 0; 43 return 0;
...@@ -59,12 +59,10 @@ pop3_get_carrier (pop3_t pop3, stream_t *pcarrier) ...@@ -59,12 +59,10 @@ pop3_get_carrier (pop3_t pop3, stream_t *pcarrier)
59 status = stream_buffer_create (&(pop3->carrier), carrier, 1024); 59 status = stream_buffer_create (&(pop3->carrier), carrier, 1024);
60 if (status != 0) 60 if (status != 0)
61 { 61 {
62 stream_release (carrier); 62 stream_destroy (&carrier);
63 return status; 63 return status;
64 } 64 }
65 } 65 }
66 /* Incremente the ref count, since we are exposing it. */
67 stream_add_ref (pop3->carrier);
68 *pcarrier = pop3->carrier; 66 *pcarrier = pop3->carrier;
69 return 0; 67 return 0;
70 } 68 }
......
...@@ -60,8 +60,6 @@ pop3_connect (pop3_t pop3, const char *host, unsigned int port) ...@@ -60,8 +60,6 @@ pop3_connect (pop3_t pop3, const char *host, unsigned int port)
60 stream_t carrier; 60 stream_t carrier;
61 status = pop3_get_carrier (pop3, &carrier); 61 status = pop3_get_carrier (pop3, &carrier);
62 POP3_CHECK_ERROR (pop3, status); 62 POP3_CHECK_ERROR (pop3, status);
63 /* A add_ref was done part of pop3_get_carrier(). */
64 stream_release (carrier);
65 } 63 }
66 else 64 else
67 { 65 {
......
...@@ -46,7 +46,7 @@ pop3_create (pop3_t *ppop3) ...@@ -46,7 +46,7 @@ pop3_create (pop3_t *ppop3)
46 pop3->ack.buf = calloc (pop3->ack.len, 1); 46 pop3->ack.buf = calloc (pop3->ack.len, 1);
47 if (pop3->ack.buf == NULL) 47 if (pop3->ack.buf == NULL)
48 { 48 {
49 pop3_destroy (pop3); 49 pop3_destroy (&pop3);
50 return MU_ERROR_NO_MEMORY; 50 return MU_ERROR_NO_MEMORY;
51 } 51 }
52 pop3->ack.ptr = pop3->ack.buf; 52 pop3->ack.ptr = pop3->ack.buf;
...@@ -56,7 +56,7 @@ pop3_create (pop3_t *ppop3) ...@@ -56,7 +56,7 @@ pop3_create (pop3_t *ppop3)
56 pop3->io.buf = calloc (pop3->io.len, 1); 56 pop3->io.buf = calloc (pop3->io.len, 1);
57 if (pop3->io.buf == NULL) 57 if (pop3->io.buf == NULL)
58 { 58 {
59 pop3_destroy (pop3); 59 pop3_destroy (&pop3);
60 return MU_ERROR_NO_MEMORY; 60 return MU_ERROR_NO_MEMORY;
61 } 61 }
62 pop3->io.ptr = pop3->io.buf; 62 pop3->io.ptr = pop3->io.buf;
......
...@@ -23,11 +23,12 @@ ...@@ -23,11 +23,12 @@
23 #include <mailutils/sys/pop3.h> 23 #include <mailutils/sys/pop3.h>
24 #include <stdlib.h> 24 #include <stdlib.h>
25 25
26 int 26 void
27 pop3_destroy (pop3_t pop3) 27 pop3_destroy (pop3_t *ppop3)
28 { 28 {
29 if (pop3) 29 if (ppop3 && *ppop3)
30 { 30 {
31 pop3_t pop3 = *ppop3;
31 if (pop3->ack.buf) 32 if (pop3->ack.buf)
32 free (pop3->ack.buf); 33 free (pop3->ack.buf);
33 34
...@@ -37,7 +38,10 @@ pop3_destroy (pop3_t pop3) ...@@ -37,7 +38,10 @@ pop3_destroy (pop3_t pop3)
37 if (pop3->timestamp) 38 if (pop3->timestamp)
38 free (pop3->timestamp); 39 free (pop3->timestamp);
39 40
41 if (pop3->carrier)
42 stream_destroy (&pop3->carrier);
43
40 free (pop3); 44 free (pop3);
45 *ppop3 = NULL;
41 } 46 }
42 return 0;
43 } 47 }
......
...@@ -26,9 +26,8 @@ ...@@ -26,9 +26,8 @@
26 #include <stdio.h> 26 #include <stdio.h>
27 #include <mailutils/sys/pop3.h> 27 #include <mailutils/sys/pop3.h>
28 28
29 static int p_add_ref __P ((iterator_t)); 29 static int p_ref __P ((iterator_t));
30 static int p_release __P ((iterator_t)); 30 static void p_destroy __P ((iterator_t *));
31 static int p_destroy __P ((iterator_t));
32 static int p_first __P ((iterator_t)); 31 static int p_first __P ((iterator_t));
33 static int p_next __P ((iterator_t)); 32 static int p_next __P ((iterator_t));
34 static int p_current __P ((iterator_t, void *)); 33 static int p_current __P ((iterator_t, void *));
...@@ -37,8 +36,7 @@ static int p_is_done __P ((iterator_t)); ...@@ -37,8 +36,7 @@ static int p_is_done __P ((iterator_t));
37 static struct _iterator_vtable p_i_vtable = 36 static struct _iterator_vtable p_i_vtable =
38 { 37 {
39 /* Base. */ 38 /* Base. */
40 p_add_ref, 39 p_ref,
41 p_release,
42 p_destroy, 40 p_destroy,
43 41
44 p_first, 42 p_first,
...@@ -56,55 +54,32 @@ pop3_iterator_create (pop3_t pop3, iterator_t *piterator) ...@@ -56,55 +54,32 @@ pop3_iterator_create (pop3_t pop3, iterator_t *piterator)
56 if (p_iterator == NULL) 54 if (p_iterator == NULL)
57 return MU_ERROR_NO_MEMORY; 55 return MU_ERROR_NO_MEMORY;
58 56
59 p_iterator->base.vtable = &p_i_vtable; 57 mu_refcount_create (&p_iterator->refcount);
60 p_iterator->ref = 1; 58 if (p_iterator->refcount == NULL)
59 {
60 free (p_iterator);
61 return MU_ERROR_NO_MEMORY;
62 }
61 p_iterator->item = NULL; 63 p_iterator->item = NULL;
62 p_iterator->done = 0; 64 p_iterator->done = 0;
63 p_iterator->pop3= pop3; 65 p_iterator->pop3= pop3;
64 monitor_create (&p_iterator->lock); 66 p_iterator->base.vtable = &p_i_vtable;
65 *piterator = &p_iterator->base; 67 *piterator = &p_iterator->base;
66 return 0; 68 return 0;
67 } 69 }
68 70
69 static int 71 static int
70 p_add_ref (iterator_t iterator) 72 p_ref (iterator_t iterator)
71 {
72 int status = 0;
73 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
74 if (p_iterator)
75 {
76 monitor_lock (p_iterator->lock);
77 status = ++p_iterator->ref;
78 monitor_unlock (p_iterator->lock);
79 }
80 return status;
81 }
82
83 static int
84 p_release (iterator_t iterator)
85 { 73 {
86 int status = 0;
87 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 74 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
88 if (p_iterator) 75 return mu_refcount_inc (p_iterator->refcount);
89 {
90 monitor_lock (p_iterator->lock);
91 status = --p_iterator->ref;
92 if (status <= 0)
93 {
94 monitor_unlock (p_iterator->lock);
95 p_destroy (iterator);
96 return 0;
97 }
98 monitor_unlock (p_iterator->lock);
99 }
100 return status;
101 } 76 }
102 77
103 static int 78 static void
104 p_destroy (iterator_t iterator) 79 p_destroy (iterator_t *piterator)
105 { 80 {
106 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 81 struct p_iterator *p_iterator = (struct p_iterator *)*piterator;
107 if (p_iterator) 82 if (mu_refcount_dec (p_iterator->refcount) == 0)
108 { 83 {
109 if (!p_iterator->done) 84 if (!p_iterator->done)
110 { 85 {
...@@ -117,10 +92,9 @@ p_destroy (iterator_t iterator) ...@@ -117,10 +92,9 @@ p_destroy (iterator_t iterator)
117 if (p_iterator->item) 92 if (p_iterator->item)
118 free (p_iterator->item); 93 free (p_iterator->item);
119 p_iterator->pop3->state = POP3_NO_STATE; 94 p_iterator->pop3->state = POP3_NO_STATE;
120 monitor_destroy (p_iterator->lock); 95 mu_refcount_destroy (&p_iterator->refcount);
121 free (p_iterator); 96 free (p_iterator);
122 } 97 }
123 return 0;
124 } 98 }
125 99
126 static int 100 static int
...@@ -138,7 +112,7 @@ p_next (iterator_t iterator) ...@@ -138,7 +112,7 @@ p_next (iterator_t iterator)
138 112
139 if (p_iterator) 113 if (p_iterator)
140 { 114 {
141 monitor_lock (p_iterator->lock); 115 mu_refcount_lock (p_iterator->refcount);
142 if (!p_iterator->done) 116 if (!p_iterator->done)
143 { 117 {
144 /* The first readline will not consume the buffer, we just need to 118 /* The first readline will not consume the buffer, we just need to
...@@ -170,7 +144,7 @@ p_next (iterator_t iterator) ...@@ -170,7 +144,7 @@ p_next (iterator_t iterator)
170 } 144 }
171 } 145 }
172 } 146 }
173 monitor_unlock (p_iterator->lock); 147 mu_refcount_unlock (p_iterator->refcount);
174 } 148 }
175 return status; 149 return status;
176 } 150 }
...@@ -182,9 +156,9 @@ p_is_done (iterator_t iterator) ...@@ -182,9 +156,9 @@ p_is_done (iterator_t iterator)
182 int status = 1; 156 int status = 1;
183 if (p_iterator) 157 if (p_iterator)
184 { 158 {
185 monitor_lock (p_iterator->lock); 159 mu_refcount_lock (p_iterator->refcount);
186 status = p_iterator->done; 160 status = p_iterator->done;
187 monitor_unlock (p_iterator->lock); 161 mu_refcount_unlock (p_iterator->refcount);
188 } 162 }
189 return status; 163 return status;
190 } 164 }
...@@ -195,13 +169,13 @@ p_current (iterator_t iterator, void *item) ...@@ -195,13 +169,13 @@ p_current (iterator_t iterator, void *item)
195 struct p_iterator *p_iterator = (struct p_iterator *)iterator; 169 struct p_iterator *p_iterator = (struct p_iterator *)iterator;
196 if (p_iterator) 170 if (p_iterator)
197 { 171 {
198 monitor_lock (p_iterator->lock); 172 mu_refcount_lock (p_iterator->refcount);
199 if (item) 173 if (item)
200 { 174 {
201 *((char **)item) = p_iterator->item; 175 *((char **)item) = p_iterator->item;
202 p_iterator->item = NULL; 176 p_iterator->item = NULL;
203 } 177 }
204 monitor_unlock (p_iterator->lock); 178 mu_refcount_unlock (p_iterator->refcount);
205 } 179 }
206 return 0; 180 return 0;
207 } 181 }
......
...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
28 #include <mailutils/sys/pop3.h> 28 #include <mailutils/sys/pop3.h>
29 29
30 /* Implementation of the stream for TOP and RETR. */ 30 /* Implementation of the stream for TOP and RETR. */
31 static int p_add_ref __P ((stream_t)); 31 static int p_ref __P ((stream_t));
32 static int p_release __P ((stream_t)); 32 static void p_destroy __P ((stream_t *));
33 static int p_destroy __P ((stream_t));
34 33
35 static int p_open __P ((stream_t, const char *, int, int)); 34 static int p_open __P ((stream_t, const char *, int, int));
36 static int p_close __P ((stream_t)); 35 static int p_close __P ((stream_t));
...@@ -58,8 +57,7 @@ static int p_is_open __P ((stream_t)); ...@@ -58,8 +57,7 @@ static int p_is_open __P ((stream_t));
58 57
59 static struct _stream_vtable p_s_vtable = 58 static struct _stream_vtable p_s_vtable =
60 { 59 {
61 p_add_ref, 60 p_ref,
62 p_release,
63 p_destroy, 61 p_destroy,
64 62
65 p_open, 63 p_open,
...@@ -96,50 +94,32 @@ pop3_stream_create (pop3_t pop3, stream_t *pstream) ...@@ -96,50 +94,32 @@ pop3_stream_create (pop3_t pop3, stream_t *pstream)
96 if (p_stream == NULL) 94 if (p_stream == NULL)
97 return MU_ERROR_NO_MEMORY; 95 return MU_ERROR_NO_MEMORY;
98 96
99 p_stream->base.vtable = &p_s_vtable; 97 mu_refcount_create (&p_stream->refcount);
100 p_stream->ref = 1; 98 if (p_stream->refcount == NULL)
99 {
100 free (p_stream);
101 return MU_ERROR_NO_MEMORY;
102 }
103
101 p_stream->done = 0; 104 p_stream->done = 0;
102 p_stream->pop3 = pop3; 105 p_stream->pop3 = pop3;
103 monitor_create (&p_stream->lock); 106 p_stream->base.vtable = &p_s_vtable;
104 *pstream = &p_stream->base; 107 *pstream = &p_stream->base;
105 return 0; 108 return 0;
106 } 109 }
107 110
108 static int 111 static int
109 p_add_ref (stream_t stream) 112 p_ref (stream_t stream)
110 {
111 struct p_stream *p_stream = (struct p_stream *)stream;
112 int status = 0;
113 if (p_stream)
114 {
115 monitor_lock (p_stream->lock);
116 status = ++p_stream->ref;
117 monitor_unlock (p_stream->lock);
118 }
119 return status;
120 }
121
122 static int
123 p_release (stream_t stream)
124 { 113 {
125 struct p_stream *p_stream = (struct p_stream *)stream; 114 struct p_stream *p_stream = (struct p_stream *)stream;
126 int status = 0; 115 return mu_refcount_inc (p_stream->refcount);
127 if (p_stream)
128 {
129 monitor_lock (p_stream->lock);
130 status = --p_stream->ref;
131 if (status <= 0)
132 p_destroy (stream);
133 monitor_unlock (p_stream->lock);
134 }
135 return status;
136 } 116 }
137 117
138 static int 118 static void
139 p_destroy (stream_t stream) 119 p_destroy (stream_t *pstream)
140 { 120 {
141 struct p_stream *p_stream = (struct p_stream *)stream; 121 struct p_stream *p_stream = (struct p_stream *)*pstream;
142 if (p_stream) 122 if (mu_refcount_dec (p_stream->refcount) == 0)
143 { 123 {
144 if (!p_stream->done) 124 if (!p_stream->done)
145 { 125 {
...@@ -150,10 +130,9 @@ p_destroy (stream_t stream) ...@@ -150,10 +130,9 @@ p_destroy (stream_t stream)
150 n = 0; 130 n = 0;
151 } 131 }
152 p_stream->pop3->state = POP3_NO_STATE; 132 p_stream->pop3->state = POP3_NO_STATE;
153 monitor_destroy (p_stream->lock); 133 mu_refcount_destroy (&p_stream->refcount);
154 free (p_stream); 134 free (p_stream);
155 } 135 }
156 return 0;
157 } 136 }
158 137
159 static int 138 static int
...@@ -180,7 +159,7 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) ...@@ -180,7 +159,7 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn)
180 char *p = buf; 159 char *p = buf;
181 if (p_stream) 160 if (p_stream)
182 { 161 {
183 monitor_lock (p_stream->lock); 162 mu_refcount_lock (p_stream->refcount);
184 if (!p_stream->done) 163 if (!p_stream->done)
185 { 164 {
186 do 165 do
...@@ -215,7 +194,7 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn) ...@@ -215,7 +194,7 @@ p_read (stream_t stream, void *buf, size_t buflen, size_t *pn)
215 } 194 }
216 while (buflen > 0); 195 while (buflen > 0);
217 } 196 }
218 monitor_unlock (p_stream->lock); 197 mu_refcount_unlock (p_stream->refcount);
219 } 198 }
220 if (pn) 199 if (pn)
221 *pn = n; 200 *pn = n;
...@@ -230,7 +209,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -230,7 +209,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn)
230 int status = 0; 209 int status = 0;
231 if (p_stream) 210 if (p_stream)
232 { 211 {
233 monitor_lock (p_stream->lock); 212 mu_refcount_lock (p_stream->refcount);
234 if (!p_stream->done) 213 if (!p_stream->done)
235 { 214 {
236 status = pop3_readline (p_stream->pop3, buf, buflen, &n); 215 status = pop3_readline (p_stream->pop3, buf, buflen, &n);
...@@ -240,7 +219,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -240,7 +219,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn)
240 p_stream->done = 1; 219 p_stream->done = 1;
241 } 220 }
242 } 221 }
243 monitor_unlock (p_stream->lock); 222 mu_refcount_unlock (p_stream->refcount);
244 } 223 }
245 if (pn) 224 if (pn)
246 *pn = n; 225 *pn = n;
......
...@@ -352,7 +352,7 @@ com_capa (char *arg) ...@@ -352,7 +352,7 @@ com_capa (char *arg)
352 printf ("Capa: %s\n", capa); 352 printf ("Capa: %s\n", capa);
353 free (capa); 353 free (capa);
354 } 354 }
355 iterator_destroy (iterator); 355 iterator_destroy (&iterator);
356 } 356 }
357 return status; 357 return status;
358 } 358 }
...@@ -377,7 +377,7 @@ com_uidl (char *arg) ...@@ -377,7 +377,7 @@ com_uidl (char *arg)
377 printf ("Msg: %d UIDL: %s\n", msgno, uidl); 377 printf ("Msg: %d UIDL: %s\n", msgno, uidl);
378 free (uidl); 378 free (uidl);
379 } 379 }
380 iterator_destroy (uidl_iterator); 380 iterator_destroy (&uidl_iterator);
381 } 381 }
382 } 382 }
383 else 383 else
...@@ -411,7 +411,7 @@ com_list (char *arg) ...@@ -411,7 +411,7 @@ com_list (char *arg)
411 pop3_list_current (list_iterator, &msgno, &size); 411 pop3_list_current (list_iterator, &msgno, &size);
412 printf ("Msg: %d Size: %d\n", msgno, size); 412 printf ("Msg: %d Size: %d\n", msgno, size);
413 } 413 }
414 iterator_destroy (list_iterator); 414 iterator_destroy (&list_iterator);
415 } 415 }
416 } 416 }
417 else 417 else
...@@ -577,7 +577,7 @@ com_top (char *arg) ...@@ -577,7 +577,7 @@ com_top (char *arg)
577 char buf[128]; 577 char buf[128];
578 while ((stream_readline (stream, buf, sizeof buf, &n) == 0) && n) 578 while ((stream_readline (stream, buf, sizeof buf, &n) == 0) && n)
579 printf ("%s", buf); 579 printf ("%s", buf);
580 stream_destroy (stream); 580 stream_destroy (&stream);
581 } 581 }
582 return 0; 582 return 0;
583 } 583 }
...@@ -602,7 +602,7 @@ com_retr (char *arg) ...@@ -602,7 +602,7 @@ com_retr (char *arg)
602 char buf[128]; 602 char buf[128];
603 while ((stream_readline (stream, buf, sizeof buf, &n) == 0) && n) 603 while ((stream_readline (stream, buf, sizeof buf, &n) == 0) && n)
604 printf ("%s", buf); 604 printf ("%s", buf);
605 stream_destroy (stream); 605 stream_destroy (&stream);
606 } 606 }
607 return 0; 607 return 0;
608 } 608 }
...@@ -639,7 +639,7 @@ com_disconnect (char *arg) ...@@ -639,7 +639,7 @@ com_disconnect (char *arg)
639 if (pop3) 639 if (pop3)
640 { 640 {
641 pop3_disconnect (pop3); 641 pop3_disconnect (pop3);
642 pop3_destroy (pop3); 642 pop3_destroy (&pop3);
643 pop3 = NULL; 643 pop3 = NULL;
644 } 644 }
645 return 0; 645 return 0;
...@@ -674,7 +674,7 @@ com_exit (char *arg) ...@@ -674,7 +674,7 @@ com_exit (char *arg)
674 if (pop3) 674 if (pop3)
675 { 675 {
676 pop3_disconnect (pop3); 676 pop3_disconnect (pop3);
677 pop3_destroy (pop3); 677 pop3_destroy (&pop3);
678 } 678 }
679 done = 1; 679 done = 1;
680 return 0; 680 return 0;
......
...@@ -26,14 +26,14 @@ ...@@ -26,14 +26,14 @@
26 #include <termios.h> 26 #include <termios.h>
27 27
28 #include <mailutils/error.h> 28 #include <mailutils/error.h>
29 #include <mailutils/monitor.h> 29 #include <mailutils/refcount.h>
30 #include <mailutils/sys/ticket.h> 30 #include <mailutils/sys/ticket.h>
31 31
32 struct _prompt_ticket 32 struct _prompt_ticket
33 { 33 {
34 struct _ticket base; 34 struct _ticket base;
35 int ref; 35 int ref;
36 monitor_t lock; 36 mu_refcount_t refcount;
37 }; 37 };
38 38
39 static void 39 static void
...@@ -53,40 +53,21 @@ echo_on(struct termios *stored_settings) ...@@ -53,40 +53,21 @@ echo_on(struct termios *stored_settings)
53 } 53 }
54 54
55 static int 55 static int
56 _prompt_add_ref (ticket_t ticket) 56 _prompt_ref (ticket_t ticket)
57 { 57 {
58 int status;
59 struct _prompt_ticket *prompt = (struct _prompt_ticket *)ticket; 58 struct _prompt_ticket *prompt = (struct _prompt_ticket *)ticket;
60 monitor_lock (prompt->lock); 59 return mu_refcount_inc (prompt->refcount);
61 status = ++prompt->ref;
62 monitor_unlock (prompt->lock);
63 return status;
64 } 60 }
65 61
66 static int 62 static void
67 _prompt_destroy (ticket_t ticket) 63 _prompt_destroy (ticket_t *pticket)
68 {
69 struct _prompt_ticket *prompt = (struct _prompt_ticket *)ticket;
70 monitor_destroy (prompt->lock);
71 free (prompt);
72 return 0;
73 }
74
75 static int
76 _prompt_release (ticket_t ticket)
77 { 64 {
78 int status; 65 struct _prompt_ticket *prompt = (struct _prompt_ticket *)*pticket;
79 struct _prompt_ticket *prompt = (struct _prompt_ticket *)ticket; 66 if (mu_refcount_dec (prompt->refcount) == 0)
80 monitor_lock (prompt->lock);
81 status = --prompt->ref;
82 if (status <= 0)
83 { 67 {
84 monitor_unlock (prompt->lock); 68 mu_refcount_destroy (&prompt->refcount);
85 _prompt_destroy (ticket); 69 free (prompt);
86 return 0;
87 } 70 }
88 monitor_unlock (prompt->lock);
89 return status;
90 } 71 }
91 72
92 static int 73 static int
...@@ -119,8 +100,7 @@ _prompt_pop (ticket_t ticket, const char *challenge, char **parg) ...@@ -119,8 +100,7 @@ _prompt_pop (ticket_t ticket, const char *challenge, char **parg)
119 100
120 static struct _ticket_vtable _prompt_vtable = 101 static struct _ticket_vtable _prompt_vtable =
121 { 102 {
122 _prompt_add_ref, 103 _prompt_ref,
123 _prompt_release,
124 _prompt_destroy, 104 _prompt_destroy,
125 105
126 _prompt_pop, 106 _prompt_pop,
...@@ -138,10 +118,14 @@ ticket_prompt_create (ticket_t *pticket) ...@@ -138,10 +118,14 @@ ticket_prompt_create (ticket_t *pticket)
138 if (prompt == NULL) 118 if (prompt == NULL)
139 return MU_ERROR_NO_MEMORY; 119 return MU_ERROR_NO_MEMORY;
140 120
141 prompt->base.vtable = &_prompt_vtable; 121 mu_refcount_create (&prompt->refcount);
142 prompt->ref = 1; 122 if (prompt->refcount == NULL)
143 monitor_create (&(prompt->lock)); 123 {
124 free (prompt);
125 return MU_ERROR_NO_MEMORY;
126 }
144 *pticket = &prompt->base; 127 *pticket = &prompt->base;
128 prompt->base.vtable = &_prompt_vtable;
145 return 0; 129 return 0;
146 } 130 }
147 131
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 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 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <stdlib.h>
23
24 #include <mailutils/monitor.h>
25 #include <mailutils/error.h>
26 #include <mailutils/sys/refcount.h>
27
28 int
29 mu_refcount_create (mu_refcount_t *prefcount)
30 {
31 mu_refcount_t refcount;
32 if (prefcount == NULL)
33 return MU_ERROR_INVALID_PARAMETER;
34 refcount = calloc (1, sizeof *refcount);
35 if (refcount == NULL)
36 return MU_ERROR_NO_MEMORY;
37 refcount->ref = 1;
38 monitor_create (&(refcount->lock));
39 *prefcount = refcount;
40 return 0;
41 }
42
43 void
44 mu_refcount_destroy (mu_refcount_t *prefcount)
45 {
46 if (prefcount && *prefcount)
47 {
48 mu_refcount_t refcount = *prefcount;
49 monitor_destroy (&refcount->lock);
50 free (refcount);
51 *prefcount = NULL;
52 }
53 }
54
55 int
56 mu_refcount_lock (mu_refcount_t refcount)
57 {
58 if (refcount)
59 return monitor_lock (refcount->lock);
60 return 0;
61 }
62
63 int
64 mu_refcount_unlock (mu_refcount_t refcount)
65 {
66 if (refcount)
67 return monitor_unlock (refcount->lock);
68 return 0;
69 }
70
71 int
72 mu_refcount_inc (mu_refcount_t refcount)
73 {
74 int count = 0;
75 if (refcount)
76 {
77 monitor_lock (refcount->lock);
78 count = ++refcount->ref;
79 monitor_unlock (refcount->lock);
80 }
81 return count;
82 }
83
84 int
85 mu_refcount_dec (mu_refcount_t refcount)
86 {
87 int count = 0;
88 if (refcount)
89 {
90 monitor_lock (refcount->lock);
91 if (refcount->ref)
92 count = --refcount->ref;
93 monitor_unlock (refcount->lock);
94 }
95 return count;
96 }
...@@ -24,30 +24,24 @@ ...@@ -24,30 +24,24 @@
24 #include <mailutils/sys/stream.h> 24 #include <mailutils/sys/stream.h>
25 25
26 int 26 int
27 stream_add_ref (stream_t stream) 27 stream_ref (stream_t stream)
28 { 28 {
29 if (stream == NULL || stream->vtable == NULL 29 if (stream == NULL || stream->vtable == NULL
30 || stream->vtable->add_ref == NULL) 30 || stream->vtable->ref == NULL)
31 return MU_ERROR_NOT_SUPPORTED; 31 return MU_ERROR_NOT_SUPPORTED;
32 return stream->vtable->add_ref (stream); 32 return stream->vtable->ref (stream);
33 } 33 }
34 34
35 int 35 void
36 stream_release (stream_t stream) 36 stream_destroy (stream_t *pstream)
37 {
38 if (stream == NULL || stream->vtable == NULL
39 || stream->vtable->release == NULL)
40 return MU_ERROR_NOT_SUPPORTED;
41 return stream->vtable->release (stream);
42 }
43
44 int
45 stream_destroy (stream_t stream)
46 { 37 {
47 if (stream == NULL || stream->vtable == NULL 38 if (pstream && *pstream)
48 || stream->vtable->destroy == NULL) 39 {
49 return MU_ERROR_NOT_SUPPORTED; 40 stream_t stream = *pstream;
50 return stream->vtable->destroy (stream); 41 if (stream->vtable && stream->vtable->destroy)
42 stream->vtable->destroy (pstream);
43 *pstream = NULL;
44 }
51 } 45 }
52 46
53 int 47 int
...@@ -158,7 +152,6 @@ stream_get_flags (stream_t stream, int *flags) ...@@ -158,7 +152,6 @@ stream_get_flags (stream_t stream, int *flags)
158 return stream->vtable->get_flags (stream, flags); 152 return stream->vtable->get_flags (stream, flags);
159 } 153 }
160 154
161
162 int 155 int
163 stream_get_state (stream_t stream, enum stream_state *state) 156 stream_get_state (stream_t stream, enum stream_state *state)
164 { 157 {
......
...@@ -32,11 +32,10 @@ ...@@ -32,11 +32,10 @@
32 #include <arpa/inet.h> 32 #include <arpa/inet.h>
33 #include <unistd.h> 33 #include <unistd.h>
34 #include <sys/time.h> 34 #include <sys/time.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 35
38 #include <mailutils/sys/tcpstream.h> 36 #include <mailutils/sys/tcpstream.h>
39 #include <mailutils/error.h> 37 #include <mailutils/error.h>
38 #include <mailutils/monitor.h>
40 39
41 /* On solaris inet_addr() return -1. */ 40 /* On solaris inet_addr() return -1. */
42 #ifndef INADDR_NONE 41 #ifndef INADDR_NONE
...@@ -47,48 +46,29 @@ static void ...@@ -47,48 +46,29 @@ static void
47 _tcp_cleanup (void *arg) 46 _tcp_cleanup (void *arg)
48 { 47 {
49 struct _tcp_instance *tcp = arg; 48 struct _tcp_instance *tcp = arg;
50 monitor_unlock (tcp->lock); 49 mu_refcount_unlock (tcp->refcount);
51 } 50 }
52 51
53 static int 52 static int
54 _tcp_add_ref (stream_t stream) 53 _tcp_ref (stream_t stream)
55 { 54 {
56 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 55 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
57 int status; 56 return mu_refcount_inc (tcp->refcount);
58 monitor_lock (tcp->lock);
59 status = ++tcp->ref;
60 monitor_unlock (tcp->lock);
61 return status;
62 } 57 }
63 58
64 static int 59 static void
65 _tcp_destroy (stream_t stream) 60 _tcp_destroy (stream_t *pstream)
66 { 61 {
67 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 62 struct _tcp_instance *tcp = (struct _tcp_instance *)*pstream;
63 if (mu_refcount_dec (tcp->refcount) == 0)
64 {
68 if (tcp->host) 65 if (tcp->host)
69 free (tcp->host); 66 free (tcp->host);
70 if (tcp->fd != -1) 67 if (tcp->fd != -1)
71 close (tcp->fd); 68 close (tcp->fd);
72 monitor_destroy (tcp->lock); 69 mu_refcount_destroy (&tcp->refcount);
73 free (tcp); 70 free (tcp);
74 return 0;
75 }
76
77 static int
78 _tcp_release (stream_t stream)
79 {
80 int status;
81 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
82 monitor_lock (tcp->lock);
83 status = --tcp->ref;
84 if (status <= 0)
85 {
86 monitor_unlock (tcp->lock);
87 _tcp_destroy (stream);
88 return 0;
89 } 71 }
90 monitor_unlock (tcp->lock);
91 return status;
92 } 72 }
93 73
94 static int 74 static int
...@@ -107,10 +87,10 @@ _tcp_close (stream_t stream) ...@@ -107,10 +87,10 @@ _tcp_close (stream_t stream)
107 { 87 {
108 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 88 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
109 89
110 monitor_lock (tcp->lock); 90 mu_refcount_lock (tcp->refcount);
111 monitor_cleanup_push (_tcp_cleanup, tcp); 91 monitor_cleanup_push (_tcp_cleanup, tcp);
112 _tcp_close0 (stream); 92 _tcp_close0 (stream);
113 monitor_unlock (tcp->lock); 93 mu_refcount_unlock (tcp->refcount);
114 monitor_cleanup_pop (0); 94 monitor_cleanup_pop (0);
115 return 0; 95 return 0;
116 } 96 }
...@@ -168,12 +148,12 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags) ...@@ -168,12 +148,12 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
168 tcp->state = TCP_STATE_RESOLVE; 148 tcp->state = TCP_STATE_RESOLVE;
169 149
170 case TCP_STATE_RESOLVE: 150 case TCP_STATE_RESOLVE:
171 memset (&soc_addr, 0, sizeof (soc_addr)); 151 memset (&soc_addr, 0, sizeof soc_addr);
172 soc_addr.sin_family = AF_INET; 152 soc_addr.sin_family = AF_INET;
173 soc_addr.sin_port = htons (tcp->port); 153 soc_addr.sin_port = htons (tcp->port);
174 soc_addr.sin_addr.s_addr = tcp->address; 154 soc_addr.sin_addr.s_addr = tcp->address;
175 155
176 if ((connect (tcp->fd, (struct sockaddr *)&soc_addr, sizeof (soc_addr))) == -1) 156 if ((connect (tcp->fd, (struct sockaddr *)&soc_addr, sizeof soc_addr)) == -1)
177 { 157 {
178 ret = errno; 158 ret = errno;
179 if (ret == EINPROGRESS || ret == EAGAIN) 159 if (ret == EINPROGRESS || ret == EAGAIN)
...@@ -188,7 +168,7 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags) ...@@ -188,7 +168,7 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
188 tcp->state = TCP_STATE_CONNECTING; 168 tcp->state = TCP_STATE_CONNECTING;
189 169
190 case TCP_STATE_CONNECTING: 170 case TCP_STATE_CONNECTING:
191 namelen = sizeof (peer_addr); 171 namelen = sizeof peer_addr;
192 if (getpeername (tcp->fd, (struct sockaddr *)&peer_addr, &namelen) == 0) 172 if (getpeername (tcp->fd, (struct sockaddr *)&peer_addr, &namelen) == 0)
193 tcp->state = TCP_STATE_CONNECTED; 173 tcp->state = TCP_STATE_CONNECTED;
194 else 174 else
...@@ -207,10 +187,10 @@ _tcp_open (stream_t stream, const char *host, int port, int flags) ...@@ -207,10 +187,10 @@ _tcp_open (stream_t stream, const char *host, int port, int flags)
207 { 187 {
208 int status; 188 int status;
209 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 189 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
210 monitor_lock (tcp->lock); 190 mu_refcount_lock (tcp->refcount);
211 monitor_cleanup_push (_tcp_cleanup, tcp); 191 monitor_cleanup_push (_tcp_cleanup, tcp);
212 status = _tcp_open0 (stream, host, port, flags); 192 status = _tcp_open0 (stream, host, port, flags);
213 monitor_unlock (tcp->lock); 193 mu_refcount_unlock (tcp->refcount);
214 monitor_cleanup_pop (0); 194 monitor_cleanup_pop (0);
215 return status; 195 return status;
216 } 196 }
...@@ -231,19 +211,18 @@ static int ...@@ -231,19 +211,18 @@ static int
231 _tcp_read (stream_t stream, void *buf, size_t buf_size, size_t *br) 211 _tcp_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
232 { 212 {
233 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 213 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
234 int bytes; 214 int bytes = 0;
215 int status = 0;
235 216
236 if (br == NULL)
237 return MU_ERROR_INVALID_PARAMETER;
238 *br = 0;
239 bytes = recv (tcp->fd, buf, buf_size, 0); 217 bytes = recv (tcp->fd, buf, buf_size, 0);
240 if (bytes == -1) 218 if (bytes == -1)
241 { 219 {
242 *br = 0; 220 bytes = 0;
243 return errno; 221 status = errno;
244 } 222 }
223 if (br)
245 *br = bytes; 224 *br = bytes;
246 return 0; 225 return status;
247 } 226 }
248 227
249 static int 228 static int
...@@ -287,19 +266,18 @@ static int ...@@ -287,19 +266,18 @@ static int
287 _tcp_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw) 266 _tcp_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
288 { 267 {
289 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 268 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
290 int bytes; 269 int bytes = 0;
270 int status = 0;
291 271
292 if (bw == NULL)
293 return MU_ERROR_INVALID_PARAMETER;
294 *bw = 0;
295 bytes = send (tcp->fd, buf, buf_size, 0); 272 bytes = send (tcp->fd, buf, buf_size, 0);
296 if (bytes == -1) 273 if (bytes == -1)
297 { 274 {
298 *bw = 0; 275 bytes = 0;
299 return errno; 276 status = errno;
300 } 277 }
278 if (bw)
301 *bw = bytes; 279 *bw = bytes;
302 return 0; 280 return status;
303 } 281 }
304 282
305 static int 283 static int
...@@ -420,8 +398,7 @@ _tcp_is_open (stream_t stream) ...@@ -420,8 +398,7 @@ _tcp_is_open (stream_t stream)
420 398
421 static struct _stream_vtable _tcp_vtable = 399 static struct _stream_vtable _tcp_vtable =
422 { 400 {
423 _tcp_add_ref, 401 _tcp_ref,
424 _tcp_release,
425 _tcp_destroy, 402 _tcp_destroy,
426 403
427 _tcp_open, 404 _tcp_open,
...@@ -461,13 +438,17 @@ stream_tcp_create (stream_t *pstream) ...@@ -461,13 +438,17 @@ stream_tcp_create (stream_t *pstream)
461 if (tcp == NULL) 438 if (tcp == NULL)
462 return MU_ERROR_NO_MEMORY; 439 return MU_ERROR_NO_MEMORY;
463 440
464 tcp->base.vtable = &_tcp_vtable; 441 mu_refcount_create (&tcp->refcount);
465 tcp->ref = 1; 442 if (tcp->refcount == NULL)
443 {
444 free (tcp);
445 return MU_ERROR_NO_MEMORY;
446 }
466 tcp->fd = -1; 447 tcp->fd = -1;
467 tcp->host = NULL; 448 tcp->host = NULL;
468 tcp->port = -1; 449 tcp->port = -1;
469 tcp->state = TCP_STATE_INIT; 450 tcp->state = TCP_STATE_INIT;
470 monitor_create (&(tcp->lock)); 451 tcp->base.vtable = &_tcp_vtable;
471 *pstream = &tcp->base; 452 *pstream = &tcp->base;
472 return 0; 453 return 0;
473 } 454 }
......
...@@ -24,30 +24,24 @@ ...@@ -24,30 +24,24 @@
24 #include <mailutils/sys/ticket.h> 24 #include <mailutils/sys/ticket.h>
25 25
26 int 26 int
27 ticket_add_ref (ticket_t ticket) 27 ticket_ref (ticket_t ticket)
28 { 28 {
29 if (ticket == NULL || ticket->vtable == NULL 29 if (ticket == NULL || ticket->vtable == NULL
30 || ticket->vtable->add_ref == NULL) 30 || ticket->vtable->ref == NULL)
31 return MU_ERROR_NOT_SUPPORTED; 31 return MU_ERROR_NOT_SUPPORTED;
32 return ticket->vtable->add_ref (ticket); 32 return ticket->vtable->ref (ticket);
33 } 33 }
34 34
35 int 35 void
36 ticket_release (ticket_t ticket) 36 ticket_destroy (ticket_t *pticket)
37 { 37 {
38 if (ticket == NULL || ticket->vtable == NULL 38 if (pticket && *pticket)
39 || ticket->vtable->release == NULL) 39 {
40 return MU_ERROR_NOT_SUPPORTED; 40 ticket_t ticket = *pticket;
41 return ticket->vtable->release (ticket); 41 if (ticket->vtable && ticket->vtable->destroy)
42 } 42 ticket->vtable->destroy (pticket);
43 43 *pticket = NULL;
44 int 44 }
45 ticket_destroy (ticket_t ticket)
46 {
47 if (ticket == NULL || ticket->vtable == NULL
48 || ticket->vtable->destroy == NULL)
49 return MU_ERROR_NOT_SUPPORTED;
50 return ticket->vtable->destroy (ticket);
51 } 45 }
52 46
53 int 47 int
......