Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Do throw an exception only when the requested factory was not found, not all the...
[simgrid.git] / src / xbt / xbt_context_java.c
1 \r
2 \r
3 #include "xbt/function_types.h"\r
4 #include "xbt/ex_interface.h"\r
5 #include "xbt/xbt_context_private.h"\r
6 #include "xbt/xbt_context_java.h"\r
7 \r
8 XBT_LOG_NEW_DEFAULT_CATEGORY(jmsg,"MSG for Java(TM)");\r
9 \r
10 /* callback: context fetching */\r
11 static ex_ctx_t*\r
12 xbt_ctx_java_ex_ctx(void);\r
13 \r
14 /* callback: termination */\r
15 static void \r
16 xbt_ctx_java_ex_terminate(xbt_ex_t *e);\r
17 \r
18 static xbt_context_t \r
19 xbt_ctx_java_factory_create_context(const char* name, xbt_main_func_t code, void_f_pvoid_t startup_func, void* startup_arg, void_f_pvoid_t cleanup_func, void* cleanup_arg, int argc, char** argv);\r
20 \r
21 static int \r
22 xbt_ctx_java_factory_create_maestro_context(xbt_context_t* maestro);\r
23 \r
24 static int\r
25 xbt_ctx_java_factory_finalize(xbt_context_factory_t* factory);\r
26 \r
27 static void \r
28 xbt_ctx_java_free(xbt_context_t context);\r
29 \r
30 static void \r
31 xbt_ctx_java_kill(xbt_context_t context);\r
32 \r
33 static void \r
34 xbt_ctx_java_schedule(xbt_context_t context);\r
35 \r
36 static void \r
37 xbt_ctx_java_yield(void);\r
38 \r
39 static void \r
40 xbt_ctx_java_start(xbt_context_t context);\r
41 \r
42 static void \r
43 xbt_ctx_java_stop(int exit_code);\r
44 \r
45 static void \r
46 xbt_ctx_java_swap(xbt_context_t context);\r
47 \r
48 static void\r
49 xbt_ctx_java_schedule(xbt_context_t context);\r
50 \r
51 static void\r
52 xbt_ctx_java_yield(void);\r
53 \r
54 static void\r
55 xbt_ctx_java_suspend(xbt_context_t context);\r
56 \r
57 static void\r
58 xbt_ctx_java_resume(xbt_context_t context);\r
59 \r
60 \r
61 /* callback: context fetching */\r
62 static ex_ctx_t*\r
63 xbt_ctx_java_ex_ctx(void) \r
64 {\r
65         return current_context->exception;\r
66 }\r
67 \r
68 /* callback: termination */\r
69 static void \r
70 xbt_ctx_java_ex_terminate(xbt_ex_t *e) \r
71 {\r
72         xbt_ex_display(e);\r
73         abort();\r
74 }\r
75 \r
76 void\r
77 xbt_ctx_java_factory_init(xbt_context_factory_t* factory)\r
78 {\r
79         /* context exception handlers */\r
80     __xbt_ex_ctx       = xbt_ctx_java_ex_ctx;\r
81     __xbt_ex_terminate = xbt_ctx_java_ex_terminate;     \r
82     \r
83     /* instantiate the context factory */\r
84         *factory = xbt_new0(s_xbt_context_factory_t,1);\r
85         \r
86         (*factory)->create_context = xbt_ctx_java_factory_create_context;\r
87         (*factory)->finalize = xbt_ctx_java_factory_finalize;\r
88         (*factory)->create_maestro_context = xbt_ctx_java_factory_create_maestro_context;\r
89         (*factory)->name = "ctx_java_factory";\r
90 }\r
91 \r
92 static int \r
93 xbt_ctx_java_factory_create_maestro_context(xbt_context_t* maestro)\r
94 {\r
95         xbt_ctx_java_t context = xbt_new0(s_xbt_ctx_java_t, 1);\r
96         \r
97         context->exception = xbt_new(ex_ctx_t,1);\r
98     XBT_CTX_INITIALIZE(context->exception);\r
99     \r
100     *maestro = (xbt_context_t)context;\r
101     \r
102     return 0;\r
103 }\r
104 \r
105 static int\r
106 xbt_ctx_java_factory_finalize(xbt_context_factory_t* factory)\r
107 {\r
108         free(maestro_context->exception);\r
109         free(*factory);\r
110         *factory = NULL;\r
111 \r
112         return 0;\r
113 }\r
114 \r
115 static xbt_context_t \r
116 xbt_ctx_java_factory_create_context(const char* name, xbt_main_func_t code, void_f_pvoid_t startup_func, void* startup_arg, void_f_pvoid_t cleanup_func, void* cleanup_arg, int argc, char** argv)\r
117 {\r
118         xbt_ctx_java_t context = xbt_new0(s_xbt_ctx_java_t,1);\r
119 \r
120         context->name = xbt_strdup(name);\r
121 \r
122         context->cleanup_func = cleanup_func;\r
123         context->cleanup_arg = cleanup_arg;\r
124 \r
125         context->exception = xbt_new(ex_ctx_t,1);\r
126         XBT_CTX_INITIALIZE(context->exception);\r
127 \r
128         context->free = xbt_ctx_java_free;                      \r
129         context->kill = xbt_ctx_java_kill;                      \r
130         context->schedule = xbt_ctx_java_schedule;\r
131         context->yield = xbt_ctx_java_yield;                    \r
132         context->start = xbt_ctx_java_start;                    \r
133         context->stop = xbt_ctx_java_stop;      \r
134         context->jprocess = (jobject)startup_arg;\r
135         context->jenv = get_current_thread_env();\r
136 \r
137         return (xbt_context_t)context;\r
138 }\r
139 \r
140 static void \r
141 xbt_ctx_java_free(xbt_context_t context)\r
142 {\r
143         if(context) \r
144         {\r
145                 xbt_ctx_java_t ctx_java = (xbt_ctx_java_t)context;\r
146                 \r
147                 free(ctx_java->name);\r
148                 \r
149                 if(ctx_java->jprocess) \r
150                 {\r
151                         jobject jprocess = ctx_java->jprocess;\r
152                         ctx_java->jprocess = NULL;\r
153 \r
154                         /* if the java process is alive join it */\r
155                         if(jprocess_is_alive(jprocess,get_current_thread_env())) \r
156                                 jprocess_join(jprocess,get_current_thread_env());\r
157                 }\r
158 \r
159                 if(ctx_java->exception) \r
160                         free(ctx_java->exception);\r
161 \r
162                 free(context);\r
163                 context = NULL;\r
164         }\r
165 }\r
166 \r
167 static void \r
168 xbt_ctx_java_kill(xbt_context_t context)\r
169 {\r
170         context->iwannadie = 1;\r
171         xbt_ctx_java_swap(context);\r
172 }\r
173 \r
174 /** \r
175  * \param context the winner\r
176  *\r
177  * Calling this function blocks the current context and schedule \a context.  \r
178  * When \a context will call xbt_context_yield, it will return\r
179  * to this function as if nothing had happened.\r
180  * \r
181  * Only the maestro can call this function to run a given process.\r
182  */\r
183 static void \r
184 xbt_ctx_java_schedule(xbt_context_t context)\r
185 {\r
186         xbt_assert0((current_context == maestro_context),"You are not supposed to run this function here!");\r
187         xbt_ctx_java_swap(context);\r
188 }\r
189 \r
190 /** \r
191  * Calling this function makes the current context yield. The context\r
192  * that scheduled it returns from xbt_context_schedule as if nothing\r
193  * had happened.\r
194  * \r
195  * Only the processes can call this function, giving back the control\r
196  * to the maestro\r
197  */\r
198 static void \r
199 xbt_ctx_java_yield(void)\r
200 {\r
201         xbt_assert0((current_context != maestro_context),"You are not supposed to run this function here!");\r
202         jprocess_unschedule(current_context);\r
203 }\r
204 \r
205 static void \r
206 xbt_ctx_java_start(xbt_context_t context)\r
207 {\r
208         jprocess_start(((xbt_ctx_java_t)context)->jprocess,get_current_thread_env());\r
209 }\r
210 \r
211 static void \r
212 xbt_ctx_java_stop(int exit_code)\r
213 {\r
214         jobject jprocess = NULL;\r
215         xbt_ctx_java_t ctx_java;\r
216 \r
217         if(current_context->cleanup_func)\r
218                 (*(current_context->cleanup_func))(current_context->cleanup_arg);\r
219 \r
220         xbt_swag_remove(current_context, context_living);\r
221         xbt_swag_insert(current_context, context_to_destroy);\r
222         \r
223         ctx_java = (xbt_ctx_java_t)current_context;\r
224         \r
225         if(ctx_java->iwannadie)\r
226         {\r
227                 /* The maestro call xbt_context_stop() with an exit code set to one */\r
228                 if(ctx_java->jprocess) \r
229                 {\r
230                         /* if the java process is alive schedule it */\r
231                         if(jprocess_is_alive(ctx_java->jprocess,get_current_thread_env())) \r
232                         {\r
233                                 jprocess_schedule(current_context);\r
234                                 jprocess = ctx_java->jprocess;\r
235                                 ctx_java->jprocess = NULL;\r
236                                 \r
237                                 /* interrupt the java process */\r
238                                 jprocess_exit(jprocess,get_current_thread_env());\r
239 \r
240                         }\r
241                 }\r
242         }\r
243         else\r
244         {\r
245                 /* the java process exits */\r
246                 jprocess = ctx_java->jprocess;\r
247                 ctx_java->jprocess = NULL;\r
248         }\r
249 \r
250         /* delete the global reference associated with the java process */\r
251         jprocess_delete_global_ref(jprocess,get_current_thread_env());  \r
252 }\r
253 \r
254 static void \r
255 xbt_ctx_java_swap(xbt_context_t context)\r
256 {\r
257         if(context) \r
258         {\r
259                 xbt_context_t self = current_context;\r
260                 \r
261                 current_context = context;\r
262                 \r
263                 jprocess_schedule(context);\r
264                 \r
265                 current_context = self;\r
266         }\r
267         \r
268         if(current_context->iwannadie)\r
269                 xbt_ctx_java_stop(1);\r
270 }\r