Rev 1072 | Rev 1086 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1072 | Rev 1084 | ||
---|---|---|---|
Line 45... | Line 45... | ||
45 | /* TODO: multi-threaded connect-to-me can cause race condition |
45 | /* TODO: multi-threaded connect-to-me can cause race condition |
46 | * on phone, add counter + thread_kill?? |
46 | * on phone, add counter + thread_kill?? |
47 | * |
47 | * |
48 | */ |
48 | */ |
49 | 49 | ||
- | 50 | #define GET_CHECK_PHONE(phone,phoneid,err) { \ |
|
- | 51 | if (phoneid > IPC_MAX_PHONES) { err; } \ |
|
- | 52 | phone = &TASK->phones[phoneid]; \ |
|
- | 53 | } |
|
- | 54 | ||
- | 55 | ||
50 | /** Return true if the method is a system method */ |
56 | /** Return true if the method is a system method */ |
51 | static inline int is_system_method(__native method) |
57 | static inline int is_system_method(__native method) |
52 | { |
58 | { |
53 | if (method <= IPC_M_LAST_SYSTEM) |
59 | if (method <= IPC_M_LAST_SYSTEM) |
54 | return 1; |
60 | return 1; |
Line 148... | Line 154... | ||
148 | phone_t *phone; |
154 | phone_t *phone; |
149 | 155 | ||
150 | if (is_system_method(method)) |
156 | if (is_system_method(method)) |
151 | return EPERM; |
157 | return EPERM; |
152 | 158 | ||
153 | phone = get_phone_and_lock(phoneid); |
159 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
154 | if (!phone) |
- | |
155 | return ENOENT; |
- | |
156 | 160 | ||
157 | ipc_call_init(&call); |
161 | ipc_call_static_init(&call); |
158 | IPC_SET_METHOD(call.data, method); |
162 | IPC_SET_METHOD(call.data, method); |
159 | IPC_SET_ARG1(call.data, arg1); |
163 | IPC_SET_ARG1(call.data, arg1); |
160 | 164 | ||
161 | ipc_call_sync(phone, &call); |
165 | ipc_call_sync(phone, &call); |
162 | 166 | ||
Line 170... | Line 174... | ||
170 | __native *reply) |
174 | __native *reply) |
171 | { |
175 | { |
172 | call_t call; |
176 | call_t call; |
173 | phone_t *phone; |
177 | phone_t *phone; |
174 | 178 | ||
175 | ipc_call_init(&call); |
179 | ipc_call_static_init(&call); |
176 | copy_from_uspace(&call.data, question, sizeof(call.data)); |
180 | copy_from_uspace(&call.data, question, sizeof(call.data)); |
177 | 181 | ||
178 | if (is_system_method(IPC_GET_METHOD(call.data))) |
182 | if (is_system_method(IPC_GET_METHOD(call.data))) |
179 | return EPERM; |
183 | return EPERM; |
180 | 184 | ||
181 | phone = get_phone_and_lock(phoneid); |
185 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
182 | if (!phone) |
- | |
183 | return ENOENT; |
- | |
184 | 186 | ||
185 | ipc_call_sync(phone, &call); |
187 | ipc_call_sync(phone, &call); |
186 | 188 | ||
187 | copy_to_uspace(reply, &call.data, sizeof(call.data)); |
189 | copy_to_uspace(reply, &call.data, sizeof(call.data)); |
188 | 190 | ||
Line 217... | Line 219... | ||
217 | return IPC_CALLRET_FATAL; |
219 | return IPC_CALLRET_FATAL; |
218 | 220 | ||
219 | if (check_call_limit()) |
221 | if (check_call_limit()) |
220 | return IPC_CALLRET_TEMPORARY; |
222 | return IPC_CALLRET_TEMPORARY; |
221 | 223 | ||
222 | phone = get_phone_and_lock(phoneid); |
224 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
223 | if (!phone) |
- | |
224 | return IPC_CALLRET_FATAL; |
- | |
225 | 225 | ||
226 | call = ipc_call_alloc(); |
226 | call = ipc_call_alloc(); |
227 | IPC_SET_METHOD(call->data, method); |
227 | IPC_SET_METHOD(call->data, method); |
228 | IPC_SET_ARG1(call->data, arg1); |
228 | IPC_SET_ARG1(call->data, arg1); |
229 | IPC_SET_ARG2(call->data, arg2); |
229 | IPC_SET_ARG2(call->data, arg2); |
Line 243... | Line 243... | ||
243 | phone_t *phone; |
243 | phone_t *phone; |
244 | 244 | ||
245 | if (check_call_limit()) |
245 | if (check_call_limit()) |
246 | return IPC_CALLRET_TEMPORARY; |
246 | return IPC_CALLRET_TEMPORARY; |
247 | 247 | ||
248 | phone = get_phone_and_lock(phoneid); |
248 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
249 | if (!phone) |
- | |
250 | return IPC_CALLRET_FATAL; |
- | |
251 | 249 | ||
252 | call = ipc_call_alloc(); |
250 | call = ipc_call_alloc(); |
253 | copy_from_uspace(&call->data, data, sizeof(call->data)); |
251 | copy_from_uspace(&call->data, data, sizeof(call->data)); |
254 | 252 | ||
255 | if (is_system_method(IPC_GET_METHOD(call->data))) { |
253 | if (is_system_method(IPC_GET_METHOD(call->data))) { |
Line 277... | Line 275... | ||
277 | 275 | ||
278 | call = get_call(callid); |
276 | call = get_call(callid); |
279 | if (!call) |
277 | if (!call) |
280 | return ENOENT; |
278 | return ENOENT; |
281 | 279 | ||
282 | phone = get_phone_and_lock(phoneid); |
280 | GET_CHECK_PHONE(phone, phoneid, { |
283 | if (!phone) { |
- | |
284 | IPC_SET_RETVAL(call->data, EFORWARD); |
281 | IPC_SET_RETVAL(call->data, EFORWARD); |
285 | ipc_answer(&TASK->answerbox, call); |
282 | ipc_answer(&TASK->answerbox, call); |
286 | return ENOENT; |
283 | return ENOENT; |
287 | } |
284 | }); |
288 | 285 | ||
289 | if (!is_forwardable(IPC_GET_METHOD(call->data))) { |
286 | if (!is_forwardable(IPC_GET_METHOD(call->data))) { |
290 | IPC_SET_RETVAL(call->data, EFORWARD); |
287 | IPC_SET_RETVAL(call->data, EFORWARD); |
291 | ipc_answer(&TASK->answerbox, call); |
288 | ipc_answer(&TASK->answerbox, call); |
292 | return EPERM; |
289 | return EPERM; |
Line 301... | Line 298... | ||
301 | } else { |
298 | } else { |
302 | IPC_SET_METHOD(call->data, method); |
299 | IPC_SET_METHOD(call->data, method); |
303 | IPC_SET_ARG1(call->data, arg1); |
300 | IPC_SET_ARG1(call->data, arg1); |
304 | } |
301 | } |
305 | 302 | ||
306 | ipc_forward(call, phone->callee, &TASK->answerbox); |
303 | ipc_forward(call, phone, &TASK->answerbox); |
307 | 304 | ||
308 | return 0; |
305 | return 0; |
309 | } |
306 | } |
310 | 307 | ||
311 | /** Send IPC answer */ |
308 | /** Send IPC answer */ |
Line 369... | Line 366... | ||
369 | __native arg2, task_id_t *taskid) |
366 | __native arg2, task_id_t *taskid) |
370 | { |
367 | { |
371 | call_t call; |
368 | call_t call; |
372 | phone_t *phone; |
369 | phone_t *phone; |
373 | 370 | ||
374 | ipc_call_init(&call); |
371 | ipc_call_static_init(&call); |
375 | IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME); |
372 | IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME); |
376 | IPC_SET_ARG1(call.data, arg1); |
373 | IPC_SET_ARG1(call.data, arg1); |
377 | IPC_SET_ARG2(call.data, arg2); |
374 | IPC_SET_ARG2(call.data, arg2); |
378 | 375 | ||
379 | phone = get_phone_and_lock(phoneid); |
376 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
380 | if (!phone) |
- | |
381 | return ENOENT; |
- | |
382 | 377 | ||
383 | ipc_call_sync(phone, &call); |
378 | ipc_call_sync(phone, &call); |
384 | 379 | ||
385 | if (!IPC_GET_RETVAL(call.data) && taskid) |
380 | if (!IPC_GET_RETVAL(call.data) && taskid) |
386 | copy_to_uspace(taskid, |
381 | copy_to_uspace(taskid, |
Line 399... | Line 394... | ||
399 | { |
394 | { |
400 | call_t call; |
395 | call_t call; |
401 | phone_t *phone; |
396 | phone_t *phone; |
402 | int newphid; |
397 | int newphid; |
403 | 398 | ||
404 | phone = get_phone_and_lock(phoneid); |
399 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
405 | if (!phone) |
- | |
406 | return ENOENT; |
- | |
407 | 400 | ||
408 | newphid = phone_alloc(); |
401 | newphid = phone_alloc(); |
409 | if (newphid < 0) |
402 | if (newphid < 0) |
410 | return ELIMIT; |
403 | return ELIMIT; |
411 | 404 | ||
412 | ipc_call_init(&call); |
405 | ipc_call_static_init(&call); |
413 | IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); |
406 | IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); |
414 | IPC_SET_ARG1(call.data, arg1); |
407 | IPC_SET_ARG1(call.data, arg1); |
415 | IPC_SET_ARG2(call.data, arg2); |
408 | IPC_SET_ARG2(call.data, arg2); |
416 | IPC_SET_ARG3(call.data, (__native)&TASK->phones[newphid]); |
409 | IPC_SET_ARG3(call.data, (__native)&TASK->phones[newphid]); |
417 | 410 |