Changeset 1be7bee in mainline
- Timestamp:
- 2019-08-07T04:20:30Z (5 years ago)
- Children:
- 70d28e8
- Parents:
- fe86d9d
- git-author:
- Michal Koutný <xm.koutny+hos@…> (2015-10-05 21:17:40)
- git-committer:
- Matthieu Riolo <matthieu.riolo@…> (2019-08-07 04:20:30)
- Location:
- uspace
- Files:
-
- 4 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/trace/trace.c
rfe86d9d r1be7bee 887 887 printf("Waiting for task to exit.\n"); 888 888 889 rc = task_wait_task_id(task_id, &texit, &retval);889 rc = task_wait_task_id(task_id, TASK_WAIT_EXIT, &texit, &retval); 890 890 if (rc != EOK) { 891 891 printf("Failed waiting for task.\n"); -
uspace/lib/c/generic/async/client.c
rfe86d9d r1be7bee 174 174 175 175 if (session != NULL) { 176 // TODO extract common part with async_connect_me_to 176 177 session_ns->iface = 0; 177 178 session->mgmt = EXCHANGE_ATOMIC; … … 195 196 196 197 /** Initialize the async framework. 197 * 198 */ 199 void __async_client_init(async_sess_t *session) 198 * @param arg_session_primary Primary session (to naming service). 199 * 200 */ 201 void __async_client_init(async_sess_t *arg_session_primary) 200 202 { 201 203 if (fibril_rmutex_initialize(&message_mutex) != EOK) 202 204 abort(); 203 205 204 if ( session== NULL) {206 if (arg_session_primary == NULL) { 205 207 session_primary = create_session_primary(); 206 208 } else { 207 session_primary = session;209 session_primary = arg_session_primary; 208 210 } 209 211 -
uspace/lib/c/generic/libc.c
rfe86d9d r1be7bee 48 48 #include "private/libc.h" 49 49 #include "private/async.h" 50 #include "private/malloc.h"51 50 #include "private/io.h" 52 51 #include "private/fibril.h" 52 #include "private/malloc.h" 53 #include "private/ns.h" // TODO maybe better filename for session_primary 54 #include "private/task.h" 55 53 56 54 57 #ifdef CONFIG_RTLD … … 108 111 if (__pcb == NULL) { 109 112 __async_client_init(NULL); 113 __task_init(NULL); 110 114 } else { 111 115 __async_client_init(__pcb->session_primary); 116 __task_init(__pcb->session_taskman); 112 117 } 113 118 __async_ports_init(); -
uspace/lib/c/generic/task.c
rfe86d9d r1be7bee 35 35 */ 36 36 37 #include <task.h>38 #include <loader/loader.h>39 #include <stdarg.h>40 #include <str.h>41 #include <ipc/ns.h>42 #include <macros.h>43 37 #include <assert.h> 44 38 #include <async.h> … … 46 40 #include <ns.h> 47 41 #include <stdlib.h> 42 #include <ipc/taskman.h> 48 43 #include <libc.h> 44 #include <loader/loader.h> 45 #include <macros.h> 46 #include <malloc.h> 47 #include <stdarg.h> 48 #include <str.h> 49 #include <task.h> 50 #include <vfs/vfs.h> 49 51 #include "private/ns.h" 50 #include <vfs/vfs.h> 52 #include "private/task.h" 53 54 static async_sess_t *session_taskman = NULL; 51 55 52 56 task_id_t task_get_id(void) … … 64 68 } 65 69 70 static async_exch_t *taskman_exchange_begin(void) 71 { 72 /* Lazy connection */ 73 if (session_taskman == NULL) { 74 // TODO unify exchange mgmt with taskman_handshake/__init 75 session_taskman = service_connect_blocking(EXCHANGE_SERIALIZE, 76 SERVICE_TASKMAN, 77 TASKMAN_CONTROL, 78 0); 79 } 80 81 if (session_taskman == NULL) { 82 return NULL; 83 } 84 85 async_exch_t *exch = async_exchange_begin(session_taskman); 86 return exch; 87 } 88 89 static void taskman_exchange_end(async_exch_t *exch) 90 { 91 async_exchange_end(exch); 92 } 93 66 94 /** Set the task name. 67 95 * … … 88 116 { 89 117 return (errno_t) __SYSCALL1(SYS_TASK_KILL, (sysarg_t) &task_id); 118 } 119 120 /** Setup waiting for a task. 121 * 122 * If the task finishes after this call succeeds, it is guaranteed that 123 * task_wait(wait, &texit, &retval) will return correct return value for 124 * the task. 125 * 126 * @param id ID of the task to setup waiting for. 127 * @param wait Information necessary for the later task_wait call is stored here. 128 * 129 * @return EOK on success, else error code. 130 */ 131 static errno_t task_setup_wait(task_id_t id, task_wait_t *wait) 132 { 133 async_exch_t *exch = taskman_exchange_begin(); 134 if (exch == NULL) 135 return EIO; 136 137 wait->aid = async_send_3(exch, TASKMAN_WAIT, LOWER32(id), UPPER32(id), 138 wait->flags, &wait->result); 139 taskman_exchange_end(exch); 140 141 return EOK; 90 142 } 91 143 … … 312 364 } 313 365 314 /** Setup waiting for a task.315 *316 * If the task finishes after this call succeeds, it is guaranteed that317 * task_wait(wait, &texit, &retval) will return correct return value for318 * the task.319 *320 * @param id ID of the task to setup waiting for.321 * @param wait Information necessary for the later task_wait call is stored here.322 *323 * @return EOK on success, else error code.324 */325 errno_t task_setup_wait(task_id_t id, task_wait_t *wait)326 {327 async_sess_t *sess_ns = get_session_primary();328 if (sess_ns == NULL)329 return EIO;330 331 async_exch_t *exch = async_exchange_begin(sess_ns);332 333 wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id),334 &wait->result);335 async_exchange_end(exch);336 337 return EOK;338 }339 340 366 /** Cancel waiting for a task. 341 367 * … … 391 417 * 392 418 * @param id ID of the task to wait for. 419 * @param flags Specify for which task output we wait 393 420 * @param texit Store type of task exit here. 394 421 * @param retval Store return value of the task here. … … 396 423 * @return EOK on success, else error code. 397 424 */ 398 errno_t task_wait_task_id(task_id_t id, task_exit_t *texit, int *retval)425 errno_t task_wait_task_id(task_id_t id, int flags, task_exit_t *texit, int *retval) 399 426 { 400 427 task_wait_t wait; 428 wait.flags = flags; 401 429 errno_t rc = task_setup_wait(id, &wait); 430 402 431 if (rc != EOK) 403 432 return rc; … … 408 437 errno_t task_retval(int val) 409 438 { 410 async_ sess_t *sess_ns = get_session_primary();411 if ( sess_ns== NULL)439 async_exch_t *exch = taskman_exchange_begin(); 440 if (exch == NULL) 412 441 return EIO; 413 442 414 async_exch_t *exch = async_exchange_begin(sess_ns); 415 errno_t rc = (errno_t) async_req_1_0(exch, NS_RETVAL, val); 416 async_exchange_end(exch); 417 443 int rc = (int) async_req_1_0(exch, TASKMAN_RETVAL, val); 444 taskman_exchange_end(exch); 445 418 446 return rc; 419 447 } 420 448 449 450 void __task_init(async_sess_t *sess) 451 { 452 assert(session_taskman == NULL); 453 session_taskman = sess; 454 } 455 421 456 /** @} 422 457 */ -
uspace/lib/c/include/ipc/ns.h
rfe86d9d r1be7bee 42 42 NS_REGISTER, 43 43 NS_REGISTER_BROKER, 44 NS_TASK_WAIT, 45 NS_ID_INTRO, 46 NS_RETVAL 44 NS_ID_INTRO 47 45 } ns_request_t; 48 46 -
uspace/lib/c/include/ipc/taskman.h
rfe86d9d r1be7bee 40 40 41 41 typedef enum { 42 TASKMAN_HELLO = IPC_FIRST_USER_METHOD, 42 TASKMAN_WAIT = IPC_FIRST_USER_METHOD, 43 TASKMAN_RETVAL 43 44 } taskman_request_t; 44 45 -
uspace/lib/c/include/loader/pcb.h
rfe86d9d r1be7bee 64 64 async_sess_t *session_primary; 65 65 66 /** Session to taskman (typically spawn parent) */ 67 async_sess_t *session_taskman; 68 66 69 /** Current working directory. */ 67 70 char *cwd; -
uspace/lib/c/include/task.h
rfe86d9d r1be7bee 42 42 #include <types/task.h> 43 43 44 #define TASK_WAIT_EXIT 0x1 45 #define TASK_WAIT_RETVAL 0x2 46 44 47 typedef struct { 48 int flags; 45 49 ipc_call_t result; 46 50 aid_t aid; 47 51 } task_wait_t; 48 52 49 struct _TASK;50 typedef struct _TASK task_t;51 53 52 54 extern task_id_t task_get_id(void); … … 63 65 __attribute__((sentinel)); 64 66 65 extern errno_t task_setup_wait(task_id_t, task_wait_t *); 67 // if there is possibility for further wait, modify task_wait 68 extern errno_t task_wait(task_wait_t *, task_exit_t *, int *); 69 extern errno_t task_wait_task_id(task_id_t, int, task_exit_t *, int *); 70 // similar to listen and socket duplication 71 extern errno_t task_wait_any(task_wait_t *, task_id_t *, task_exit_t *, int *, 72 task_wait_t *); 73 74 //extern int task_wait_any(int, task_exit_t *, int *); 75 // alternative 76 // task_wait_t is output param, actual result is obtained via task_wait call 77 //extern int task_wait_any(task_wait_t *, int); 78 66 79 extern void task_cancel_wait(task_wait_t *); 67 extern errno_t task_wait(task_wait_t *, task_exit_t *, int *); 68 extern errno_t task_wait_task_id(task_id_t, task_exit_t *, int *); 80 69 81 extern errno_t task_retval(int); 82 //TODO 83 //extern int task_exit(int); 70 84 71 85 #endif -
uspace/lib/posix/src/sys/wait.c
rfe86d9d r1be7bee 101 101 assert(options == 0 /* None of the options are supported. */); 102 102 103 int flags = TASK_WAIT_RETVAL | TASK_WAIT_EXIT; 103 104 task_exit_t texit; 104 105 int retval; 105 106 106 if (failed(task_wait_task_id((task_id_t) pid, &texit, &retval))) { 107 // TODO repeat wait for both retval and exit 108 if (failed(task_wait_task_id((task_id_t) pid, flags, &texit, &retval))) { 107 109 /* Unable to retrieve status. */ 108 110 return (pid_t) -1; -
uspace/srv/loader/main.c
rfe86d9d r1be7bee 84 84 static async_sess_t *session_primary = NULL; 85 85 86 /** Session to taskman (typically our spawner) */ 87 static async_sess_t *session_taskman = NULL; 88 86 89 /** Current working directory */ 87 90 static char *cwd = NULL; … … 335 338 336 339 pcb.session_primary = session_primary; 340 pcb.session_taskman = session_taskman; 337 341 338 342 pcb.cwd = cwd; … … 452 456 } 453 457 458 /** Handshake with taskman 459 * 460 * Taskman is our spawn parent, i.e. PHONE_INITIAL is connected to it. 461 * Goal of the handshake is to obtain phone to naming service and also keep the 462 * session to taskman. 463 * 464 * @return EOK on success, for errors see taskman_handshake() 465 */ 454 466 static errno_t ldr_taskman_handshake(void) 455 467 { 468 assert(session_primary == NULL); 469 assert(session_taskman == NULL); 470 456 471 errno_t retval = EOK; 457 472 … … 463 478 } 464 479 465 async_sess_t *session_tm = async_session_primary_swap(session_primary); 466 (void)async_hangup(session_tm); 480 session_taskman = async_session_primary_swap(session_primary); 467 481 468 482 handshake_complete = true; -
uspace/srv/ns/ns.c
rfe86d9d r1be7bee 43 43 #include <stdio.h> 44 44 #include <errno.h> 45 #include <macros.h>46 45 #include "ns.h" 47 46 #include "service.h" … … 96 95 retval = EOK; 97 96 break; 98 case NS_TASK_WAIT:99 id = (task_id_t)100 MERGE_LOUP32(ipc_get_arg1(&call), ipc_get_arg2(&call));101 wait_for_task(id, &call);102 continue;103 97 case NS_ID_INTRO: 104 98 retval = ns_task_id_intro(&call); 105 break;106 case NS_RETVAL:107 // TODO move to taskman108 retval = EOK;109 //retval = ns_task_retval(&call);110 99 break; 111 100 default: -
uspace/srv/taskman/Makefile
rfe86d9d r1be7bee 32 32 33 33 SOURCES = \ 34 main.c 34 main.c \ 35 task.c 35 36 36 37 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/taskman/main.c
rfe86d9d r1be7bee 34 34 #include <ipc/taskman.h> 35 35 #include <loader/loader.h> 36 #include <macros.h> 36 37 #include <ns.h> 37 38 #include <stdio.h> 38 39 #include <stdlib.h> 39 40 40 #define NAME "taskman" 41 #include "task.h" 42 #include "taskman.h" 41 43 42 44 //TODO move to appropriate header file … … 56 58 static void connect_to_loader(ipc_callid_t iid, ipc_call_t *icall) 57 59 { 60 //TODO explain why we don't explicitly accept connection request 58 61 /* Spawn a loader. */ 59 62 int rc = loader_spawn("loader"); … … 99 102 } 100 103 104 static void taskman_ctl_wait(ipc_callid_t iid, ipc_call_t *icall) 105 { 106 task_id_t id = (task_id_t) 107 MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall)); 108 int flags = IPC_GET_ARG3(*icall); 109 110 wait_for_task(id, flags, iid, icall); 111 } 112 113 static void taskman_ctl_retval(ipc_callid_t iid, ipc_call_t *icall) 114 { 115 printf("%s:%i\n", __func__, __LINE__); 116 int rc = task_set_retval(icall); 117 async_answer_0(iid, rc); 118 } 119 120 static void control_connection_loop(void) 121 { 122 while (true) { 123 ipc_call_t call; 124 ipc_callid_t callid = async_get_call(&call); 125 126 if (!IPC_GET_IMETHOD(call)) { 127 /* Client disconnected */ 128 break; 129 } 130 131 switch (IPC_GET_IMETHOD(call)) { 132 case TASKMAN_WAIT: 133 taskman_ctl_wait(callid, &call); 134 break; 135 case TASKMAN_RETVAL: 136 taskman_ctl_retval(callid, &call); 137 break; 138 default: 139 async_answer_0(callid, ENOENT); 140 } 141 } 142 } 143 144 static void control_connection(ipc_callid_t iid, ipc_call_t *icall) 145 { 146 /* First, accept connection */ 147 async_answer_0(iid, EOK); 148 149 // TODO register task to hash table 150 control_connection_loop(); 151 } 152 101 153 static void loader_callback(ipc_callid_t iid, ipc_call_t *icall) 102 154 { … … 134 186 loader_to_ns(iid, icall); 135 187 break; 188 case TASKMAN_CONTROL: 189 control_connection(iid, icall); 190 // ---- interrupt here ---- 191 // implement control connection body (setup wait) 192 // ------------------------ 193 break; 136 194 default: 137 195 /* Unknown interface */ … … 146 204 case TASKMAN_LOADER_CALLBACK: 147 205 loader_callback(iid, icall); 206 // TODO register task to hashtable 207 control_connection_loop(); 148 208 break; 149 209 default: … … 161 221 162 222 prodcons_initialize(&sess_queue); 223 int rc = task_init(); 224 if (rc != EOK) { 225 return rc; 226 } 163 227 164 228 /* We're service too */ 165 intrc = service_register(SERVICE_TASKMAN);229 rc = service_register(SERVICE_TASKMAN); 166 230 if (rc != EOK) { 167 231 printf("Cannot register at naming service (%i).", rc);
Note:
See TracChangeset
for help on using the changeset viewer.