1 /*
2 **  GNU Pth - The GNU Portable Threads
3 **  Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
4 **
5 **  This file is part of GNU Pth, a non-preemptive thread scheduling
6 **  library which can be found at http://www.gnu.org/software/pth/.
7 **
8 **  This library is free software; you can redistribute it and/or
9 **  modify it under the terms of the GNU Lesser General Public
10 **  License as published by the Free Software Foundation; either
11 **  version 2.1 of the License, or (at your option) any later version.
12 **
13 **  This library is distributed in the hope that it will be useful,
14 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 **  Lesser General Public License for more details.
17 **
18 **  You should have received a copy of the GNU Lesser General Public
19 **  License along with this library; if not, write to the Free Software
20 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 **  USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
22 **
23 **  pth_clean.c: Pth per-thread cleanup handler
24 */
25                              /* ``The concept seems to be clear by now.
26                                   It has been defined several times
27                                   by example of what it is not.''
28                                                        -- Unknown */
29 #include "pth_p.h"
30 
31 #if cpp
32 
33 typedef struct pth_cleanup_st pth_cleanup_t;
34 struct pth_cleanup_st {
35     pth_cleanup_t *next;
36     void (*func)(void *);
37     void *arg;
38 };
39 
40 #endif /* cpp */
41 
pth_cleanup_push(void (* func)(void *),void * arg)42 int pth_cleanup_push(void (*func)(void *), void *arg)
43 {
44     pth_cleanup_t *cleanup;
45 
46     if (func == NULL)
47         return pth_error(FALSE, EINVAL);
48     if ((cleanup = (pth_cleanup_t *)malloc(sizeof(pth_cleanup_t))) == NULL)
49         return pth_error(FALSE, ENOMEM);
50     cleanup->func = func;
51     cleanup->arg  = arg;
52     cleanup->next = pth_current->cleanups;
53     pth_current->cleanups = cleanup;
54     return TRUE;
55 }
56 
pth_cleanup_pop(int execute)57 int pth_cleanup_pop(int execute)
58 {
59     pth_cleanup_t *cleanup;
60     int rc;
61 
62     rc = FALSE;
63     if ((cleanup = pth_current->cleanups) != NULL) {
64         pth_current->cleanups = cleanup->next;
65         if (execute)
66             cleanup->func(cleanup->arg);
67         free(cleanup);
68         rc = TRUE;
69     }
70     return rc;
71 }
72 
pth_cleanup_popall(pth_t t,int execute)73 intern void pth_cleanup_popall(pth_t t, int execute)
74 {
75     pth_cleanup_t *cleanup;
76 
77     while ((cleanup = t->cleanups) != NULL) {
78         t->cleanups = cleanup->next;
79         if (execute)
80             cleanup->func(cleanup->arg);
81         free(cleanup);
82     }
83     return;
84 }
85 
86