]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - src/syncobj.c
Prepared test cases for executors (thread specific data)
[frescor/forb.git] / src / syncobj.c
1 //----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politecnica  Valencia,           SPAIN
9 //    Czech Technical University in Prague,  CZECH REPUBLIC
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org
17 //
18 //        The FRESCOR project (FP6/2005/IST/5-034026) is funded
19 //        in part by the European Union Sixth Framework Programme
20 //        The European Union is not liable of any use that may be
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 // This file is part of DTM (Distributed Transaction Manager)
32 //
33 // DTM is free software; you can redistribute it and/or modify it
34 // under terms of the GNU General Public License as published by the
35 // Free Software Foundation; either version 2, or (at your option) any
36 // later version.  DTM is distributed in the hope that it will be
37 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
38 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 // General Public License for more details. You should have received a
40 // copy of the GNU General Public License along with DTM; see file
41 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
42 // Cambridge, MA 02139, USA.
43 //
44 // As a special exception, including DTM header files in a file,
45 // instantiating DTM generics or templates, or linking other files
46 // with DTM objects to produce an executable application, does not
47 // by itself cause the resulting executable application to be covered
48 // by the GNU General Public License. This exception does not
49 // however invalidate any other reasons why the executable file might be
50 // covered by the GNU Public License.
51 // -----------------------------------------------------------------------
52
53 /**
54  * @file 
55  *
56  * @brief Synchronization object used in FORB
57  *
58  * @author
59  *      Michael Gonzalez Harbour <mgh@unican.es>
60  *      Michal Sojka <sojkam1@fel.cvut.cz>
61  *      Daniel Sangorrin <daniel.sangorrin@unican.es>
62  *
63  * @comments
64  *
65  * This module contains the definition of the data object and operations to
66  * create a pool of objects, obtain the id of an unused object, wait upon it,
67  * signal it, and finish using it.
68  *
69  * @license
70  *
71  * See the COPYING file in the FORB's root directory
72  *
73  */
74
75 #include "syncobj.h"
76
77 /**
78  * Initializes the synchronization object.
79  *
80  * @return Zero on success, FOSA error code on error.
81  **/
82
83 int forb_syncobj_init(forb_syncobj_t *syncobj, int ceiling)
84 {
85         int err;
86
87         err = fosa_cond_init(&syncobj->cond);
88         if (err != 0) return err;
89
90         syncobj->is_work_done = false;
91
92         err = fosa_mutex_init(&syncobj->mutex, ceiling);
93         if (err != 0) return err;
94
95         return 0;
96 }
97
98 /**
99  * Destroys all resources related to the synchronization object.
100  **/
101
102 int forb_syncobj_destroy(forb_syncobj_t *syncobj)
103 {
104         int err;
105
106         err = fosa_cond_destroy(&syncobj->cond);
107         if (err != 0) return err;
108         
109         err = fosa_mutex_destroy(&syncobj->mutex);
110         if (err != 0) return err;
111
112         return 0;
113 }
114
115 /**
116  * Signal the synchronization object.
117  **/
118
119 int forb_syncobj_signal(forb_syncobj_t *syncobj)
120 {
121         int err;
122
123         err = fosa_mutex_lock(&syncobj->mutex);
124         if (err != 0) return err;
125
126         syncobj->is_work_done = true;
127
128         err = fosa_cond_signal(&syncobj->cond);
129         if (err != 0) goto locked_error;
130
131         err = fosa_mutex_unlock(&syncobj->mutex);
132         if (err != 0) return err;
133
134         return 0;
135
136 locked_error:
137         fosa_mutex_unlock(&syncobj->mutex);
138         return err;
139 }
140
141 static void
142 syncobj_cleanup(void *syncobj)
143 {
144         forb_syncobj_t *s = syncobj;
145         fosa_mutex_unlock(&s->mutex);
146 }
147
148 /**
149  * Wait on the synchronization object.
150  **/
151
152 int forb_syncobj_wait(forb_syncobj_t *syncobj)
153 {
154         int err = 0;
155
156         err = fosa_mutex_lock(&syncobj->mutex);
157         if (err != 0) return err;
158         pthread_cleanup_push(syncobj_cleanup, syncobj);
159
160         while (syncobj->is_work_done == false) {
161                 err = fosa_cond_wait(&syncobj->cond,
162                                      &syncobj->mutex);
163                 if (err != 0) goto locked_error;
164         }
165         
166         syncobj->is_work_done = false;
167
168 locked_error:;
169         pthread_cleanup_pop(1);
170         return err;
171 ;
172 }
173
174 /**
175  * Wait on the synchronization object with a timeout.
176  *
177  * @return Zero on success, ETIMEDOUT on timeout or other FOSA error
178  * code on error.
179  **/
180
181 int forb_syncobj_timedwait(forb_syncobj_t *syncobj,
182                            const struct timespec *abstime)
183 {
184         int err = 0;
185
186         err = fosa_mutex_lock(&syncobj->mutex);
187         if (err != 0) return err;
188         pthread_cleanup_push(syncobj_cleanup, syncobj);
189
190         while (syncobj->is_work_done == false) {
191                 err = fosa_cond_timedwait(&syncobj->cond,
192                                           &syncobj->mutex,
193                                           abstime);
194                 if (err != 0) goto locked_error;
195         }
196
197         syncobj->is_work_done = false;
198
199 locked_error:;
200         pthread_cleanup_pop(1);
201         return err;
202 }