Changes in uspace/lib/c/generic/task.c [1c635d6:9f5cf68] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/task.c
r1c635d6 r9f5cf68 2 2 * Copyright (c) 2006 Jakub Jermar 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2014 Martin Sucha5 4 * All rights reserved. 6 5 * … … 95 94 * 96 95 * @param id If not NULL, the ID of the task is stored here on success. 97 * @param wait If not NULL, setup waiting for task's return value and store98 * the information necessary for waiting here on success.99 96 * @param path Pathname of the binary to execute. 100 97 * @param argv Command-line arguments. … … 103 100 * 104 101 */ 105 int task_spawnv(task_id_t *id, task_wait_t *wait, const char *path, 106 const char *const args[]) 102 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 107 103 { 108 104 /* Send default files */ … … 129 125 files[3] = NULL; 130 126 131 return task_spawnvf(id, wait,path, args, files);127 return task_spawnvf(id, path, args, files); 132 128 } 133 129 … … 139 135 * 140 136 * @param id If not NULL, the ID of the task is stored here on success. 141 * @param wait If not NULL, setup waiting for task's return value and store142 * the information necessary for waiting here on success.143 137 * @param path Pathname of the binary to execute. 144 138 * @param argv Command-line arguments. … … 148 142 * 149 143 */ 150 int task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path,151 const char *const args[],int *const files[])144 int task_spawnvf(task_id_t *id, const char *path, const char *const args[], 145 int *const files[]) 152 146 { 153 147 /* Connect to a program loader. */ … … 156 150 return EREFUSED; 157 151 158 bool wait_initialized = false;159 160 152 /* Get task ID. */ 161 153 task_id_t task_id; … … 189 181 goto error; 190 182 191 /* Setup waiting for return value if needed */192 if (wait) {193 rc = task_setup_wait(task_id, wait);194 if (rc != EOK)195 goto error;196 wait_initialized = true;197 }198 199 183 /* Run it. */ 200 184 rc = loader_run(ldr); … … 209 193 210 194 error: 211 if (wait_initialized)212 task_cancel_wait(wait);213 214 195 /* Error exit */ 215 196 loader_abort(ldr); … … 223 204 * 224 205 * @param id If not NULL, the ID of the task is stored here on success. 225 * @param wait If not NULL, setup waiting for task's return value and store226 * the information necessary for waiting here on success.227 206 * @param path Pathname of the binary to execute. 228 207 * @param cnt Number of arguments. … … 232 211 * 233 212 */ 234 int task_spawn(task_id_t *task_id, task_wait_t *wait, const char *path, 235 int cnt, va_list ap) 213 int task_spawn(task_id_t *task_id, const char *path, int cnt, va_list ap) 236 214 { 237 215 /* Allocate argument list. */ … … 249 227 250 228 /* Spawn task. */ 251 int rc = task_spawnv(task_id, wait,path, arglist);229 int rc = task_spawnv(task_id, path, arglist); 252 230 253 231 /* Free argument list. */ … … 262 240 * 263 241 * @param id If not NULL, the ID of the task is stored here on success. 264 * @param wait If not NULL, setup waiting for task's return value and store265 * the information necessary for waiting here on success.266 242 * @param path Pathname of the binary to execute. 267 243 * @param ... Command-line arguments. … … 270 246 * 271 247 */ 272 int task_spawnl(task_id_t *task_id, task_wait_t *wait,const char *path, ...)248 int task_spawnl(task_id_t *task_id, const char *path, ...) 273 249 { 274 250 /* Count the number of arguments. */ … … 286 262 287 263 va_start(ap, path); 288 int rc = task_spawn(task_id, wait,path, cnt, ap);264 int rc = task_spawn(task_id, path, cnt, ap); 289 265 va_end(ap); 290 266 … … 292 268 } 293 269 294 /** Setup waiting for a task. 295 * 296 * If the task finishes after this call succeeds, it is guaranteed that 297 * task_wait(wait, &texit, &retval) will return correct return value for 298 * the task. 299 * 300 * @param id ID of the task to setup waiting for. 301 * @param wait Information necessary for the later task_wait call is stored here. 302 * 303 * @return EOK on success, else error code. 304 */ 305 int task_setup_wait(task_id_t id, task_wait_t *wait) 306 { 307 async_exch_t *exch = async_exchange_begin(session_ns); 308 wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id), 309 &wait->result); 310 async_exchange_end(exch); 311 312 return EOK; 313 } 314 315 /** Cancel waiting for a task. 316 * 317 * This can be called *instead of* task_wait if the caller is not interested 318 * in waiting for the task anymore. 319 * 320 * This function cannot be called if the task_wait was already called. 321 * 322 * @param wait task_wait_t previously initialized by task_setup_wait. 323 */ 324 void task_cancel_wait(task_wait_t *wait) { 325 async_forget(wait->aid); 326 } 327 328 /** Wait for a task to finish. 329 * 330 * This function returns correct values even if the task finished in 331 * between task_setup_wait and this task_wait call. 332 * 333 * This function cannot be called more than once with the same task_wait_t 334 * (it can be reused, but must be reinitialized with task_setup_wait first) 335 * 336 * @param wait task_wait_t previously initialized by task_setup_wait. 337 * @param texit Store type of task exit here. 338 * @param retval Store return value of the task here. 339 * 340 * @return EOK on success, else error code. 341 */ 342 int task_wait(task_wait_t *wait, task_exit_t *texit, int *retval) 270 int task_wait(task_id_t id, task_exit_t *texit, int *retval) 343 271 { 344 272 assert(texit); 345 273 assert(retval); 346 347 sysarg_t rc; 348 async_wait_for(wait->aid, &rc); 349 350 if (rc == EOK) { 351 *texit = IPC_GET_ARG1(wait->result); 352 *retval = IPC_GET_ARG2(wait->result); 353 } 354 355 return rc; 356 } 357 358 /** Wait for a task to finish by its id. 359 * 360 * Note that this will fail with ENOENT if the task id is not registered in ns 361 * (e.g. if the task finished). If you are spawning a task and need to wait 362 * for its completion, use wait parameter of the task_spawn* functions instead 363 * to prevent a race where the task exits before you may have a chance to wait 364 * wait for it. 365 * 366 * @param id ID of the task to wait for. 367 * @param texit Store type of task exit here. 368 * @param retval Store return value of the task here. 369 * 370 * @return EOK on success, else error code. 371 */ 372 int task_wait_task_id(task_id_t id, task_exit_t *texit, int *retval) 373 { 374 task_wait_t wait; 375 int rc = task_setup_wait(id, &wait); 376 if (rc != EOK) 377 return rc; 378 379 return task_wait(&wait, texit, retval); 274 275 async_exch_t *exch = async_exchange_begin(session_ns); 276 sysarg_t te, rv; 277 int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id), 278 UPPER32(id), &te, &rv); 279 async_exchange_end(exch); 280 281 *texit = te; 282 *retval = rv; 283 284 return rc; 380 285 } 381 286
Note:
See TracChangeset
for help on using the changeset viewer.