Rev 1040 | Rev 1063 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1040 | Rev 1060 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | #include <mm/page.h> |
33 | #include <mm/page.h> |
34 | #include <memstr.h> |
34 | #include <memstr.h> |
35 | #include <debug.h> |
35 | #include <debug.h> |
36 | #include <ipc/ipc.h> |
36 | #include <ipc/ipc.h> |
37 | #include <ipc/sysipc.h> |
37 | #include <ipc/sysipc.h> |
- | 38 | ||
- | 39 | ||
38 | #include <print.h> |
40 | #include <print.h> |
- | 41 | #include <arch.h> |
|
- | 42 | #include <proc/thread.h> |
|
39 | 43 | ||
40 | /* TODO: multi-threaded connect-to-me can cause race condition |
44 | /* TODO: multi-threaded connect-to-me can cause race condition |
41 | * on phone, add counter + thread_kill?? |
45 | * on phone, add counter + thread_kill?? |
42 | * |
46 | * |
43 | */ |
47 | */ |
Line 136... | Line 140... | ||
136 | */ |
140 | */ |
137 | static inline int answer_will_preprocess(call_t *call) |
141 | static inline int answer_will_preprocess(call_t *call) |
138 | { |
142 | { |
139 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECTTOME) |
143 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECTTOME) |
140 | return 1; |
144 | return 1; |
- | 145 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECTMETO) |
|
- | 146 | return 1; |
|
141 | return 0; |
147 | return 0; |
142 | } |
148 | } |
143 | 149 | ||
144 | /** Interpret process answer as control information */ |
150 | /** Interpret process answer as control information */ |
145 | static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata) |
151 | static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata) |
Line 153... | Line 159... | ||
153 | phone_dealloc(phoneid); |
159 | phone_dealloc(phoneid); |
154 | } else { |
160 | } else { |
155 | /* The connection was accepted */ |
161 | /* The connection was accepted */ |
156 | phone_connect(phoneid,&answer->sender->answerbox); |
162 | phone_connect(phoneid,&answer->sender->answerbox); |
157 | } |
163 | } |
- | 164 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTMETO) { |
|
- | 165 | /* If the users accepted call, connect */ |
|
- | 166 | if (!IPC_GET_RETVAL(answer->data)) { |
|
- | 167 | printf("Connecting Phone %P\n",IPC_GET_ARG3(*olddata)); |
|
- | 168 | ipc_phone_connect((phone_t *)IPC_GET_ARG3(*olddata), |
|
- | 169 | &TASK->answerbox); |
|
- | 170 | } |
|
158 | } |
171 | } |
159 | } |
172 | } |
160 | 173 | ||
161 | /****************************************************/ |
174 | /****************************************************/ |
162 | /* Functions called to process received call/answer |
175 | /* Functions called to process received call/answer |
Line 316... | Line 329... | ||
316 | } |
329 | } |
317 | 330 | ||
318 | /** Forward received call to another destination |
331 | /** Forward received call to another destination |
319 | * |
332 | * |
320 | * The arg1 and arg2 are changed in the forwarded message |
333 | * The arg1 and arg2 are changed in the forwarded message |
- | 334 | * |
|
- | 335 | * Warning: If implementing non-fast version, make sure that |
|
- | 336 | * arg3 is not rewritten for certain system IPC |
|
321 | */ |
337 | */ |
322 | __native sys_ipc_forward_fast(__native callid, __native phoneid, |
338 | __native sys_ipc_forward_fast(__native callid, __native phoneid, |
323 | __native method, __native arg1) |
339 | __native method, __native arg1) |
324 | { |
340 | { |
325 | call_t *call; |
341 | call_t *call; |
Line 434... | Line 450... | ||
434 | 450 | ||
435 | if (!IPC_GET_RETVAL(call.data) && taskid) |
451 | if (!IPC_GET_RETVAL(call.data) && taskid) |
436 | copy_to_uspace(taskid, |
452 | copy_to_uspace(taskid, |
437 | &phone->callee->task->taskid, |
453 | &phone->callee->task->taskid, |
438 | sizeof(TASK->taskid)); |
454 | sizeof(TASK->taskid)); |
- | 455 | ||
439 | return IPC_GET_RETVAL(call.data); |
456 | return IPC_GET_RETVAL(call.data); |
440 | } |
457 | } |
441 | 458 | ||
442 | /** Ask target process to connect me somewhere |
459 | /** Ask target process to connect me somewhere |
443 | * |
460 | * |
Line 446... | Line 463... | ||
446 | __native sys_ipc_connect_me_to(__native phoneid, __native arg1, |
463 | __native sys_ipc_connect_me_to(__native phoneid, __native arg1, |
447 | __native arg2) |
464 | __native arg2) |
448 | { |
465 | { |
449 | call_t call; |
466 | call_t call; |
450 | phone_t *phone; |
467 | phone_t *phone; |
- | 468 | int newphid; |
|
451 | 469 | ||
452 | phone = get_phone(phoneid); |
470 | phone = get_phone(phoneid); |
453 | if (!phone) |
471 | if (!phone) |
454 | return ENOENT; |
472 | return ENOENT; |
455 | 473 | ||
- | 474 | newphid = phone_alloc(); |
|
- | 475 | if (newphid < 0) |
|
- | 476 | return ELIMIT; |
|
- | 477 | ||
456 | ipc_call_init(&call); |
478 | ipc_call_init(&call); |
457 | IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); |
479 | IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); |
458 | IPC_SET_ARG1(call.data, arg1); |
480 | IPC_SET_ARG1(call.data, arg1); |
459 | IPC_SET_ARG2(call.data, arg2); |
481 | IPC_SET_ARG2(call.data, arg2); |
- | 482 | IPC_SET_ARG3(call.data, (__native)&TASK->phones[newphid]); |
|
460 | 483 | ||
461 | ipc_call_sync(phone, &call); |
484 | ipc_call_sync(phone, &call); |
- | 485 | ||
462 | if (!IPC_GET_RETVAL(call.data)) { |
486 | if (IPC_GET_RETVAL(call.data)) { /* Connection failed */ |
- | 487 | phone_dealloc(newphid); |
|
463 | /* Everybody accepted, we should be connected by now */ |
488 | return IPC_GET_RETVAL(call.data); |
464 | } |
489 | } |
465 | 490 | ||
466 | return 0; |
491 | return newphid; |
467 | } |
492 | } |
468 | 493 | ||
469 | /** Wait for incoming ipc call or answer |
494 | /** Wait for incoming ipc call or answer |
470 | * |
495 | * |
471 | * Generic function - can serve either as inkernel or userspace call |
496 | * Generic function - can serve either as inkernel or userspace call |
Line 483... | Line 508... | ||
483 | { |
508 | { |
484 | call_t *call; |
509 | call_t *call; |
485 | 510 | ||
486 | restart: |
511 | restart: |
487 | call = ipc_wait_for_call(&TASK->answerbox, flags); |
512 | call = ipc_wait_for_call(&TASK->answerbox, flags); |
488 | printf("Received call %P from sender: %P\n", call, call->sender); |
- | |
489 | 513 | ||
490 | if (call->flags & IPC_CALL_ANSWERED) { |
514 | if (call->flags & IPC_CALL_ANSWERED) { |
491 | if (process_answer(&TASK->answerbox, call)) |
515 | if (process_answer(&TASK->answerbox, call)) |
492 | goto restart; |
516 | goto restart; |
493 | 517 |