Changeset d054ad3 in mainline
- Timestamp:
- 2018-07-09T18:36:33Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2d56e2e
- Parents:
- 87337dc5
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-05 16:39:15)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-07-09 18:36:33)
- Location:
- uspace/lib/c
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/client.c
r87337dc5 rd054ad3 241 241 * 242 242 */ 243 static void reply_received(void *arg, errno_t retval, ipc_call_t *data) 244 { 245 assert(arg); 243 void async_reply_received(ipc_call_t *data) 244 { 245 amsg_t *msg = data->label; 246 if (!msg) 247 return; 246 248 247 249 futex_lock(&async_futex); 248 250 249 amsg_t *msg = (amsg_t *) arg; 250 msg->retval = retval; 251 msg->retval = IPC_GET_RETVAL(*data); 251 252 252 253 /* Copy data after futex_down, just in case the call was detached */ … … 302 303 msg->wdata.active = true; 303 304 304 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg, 305 reply_received); 305 errno_t rc = ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, 306 arg4, msg); 307 if (rc != EOK) { 308 msg->retval = rc; 309 msg->done = true; 310 } 306 311 307 312 return (aid_t) msg; … … 340 345 msg->wdata.active = true; 341 346 342 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5, 343 msg, reply_received); 347 errno_t rc = ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, 348 arg4, arg5, msg); 349 if (rc != EOK) { 350 msg->retval = rc; 351 msg->done = true; 352 } 344 353 345 354 return (aid_t) msg; … … 653 662 { 654 663 if (exch != NULL) 655 ipc_call_async_0(exch->phone, imethod, NULL , NULL);664 ipc_call_async_0(exch->phone, imethod, NULL); 656 665 } 657 666 … … 659 668 { 660 669 if (exch != NULL) 661 ipc_call_async_1(exch->phone, imethod, arg1, NULL , NULL);670 ipc_call_async_1(exch->phone, imethod, arg1, NULL); 662 671 } 663 672 … … 666 675 { 667 676 if (exch != NULL) 668 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL , NULL);677 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL); 669 678 } 670 679 … … 673 682 { 674 683 if (exch != NULL) 675 ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL, 676 NULL); 684 ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL); 677 685 } 678 686 … … 682 690 if (exch != NULL) 683 691 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, 684 NULL , NULL);692 NULL); 685 693 } 686 694 … … 690 698 if (exch != NULL) 691 699 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, 692 arg5, NULL , NULL);700 arg5, NULL); 693 701 } 694 702 … … 710 718 msg->wdata.active = true; 711 719 712 ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, (sysarg_t) iface, arg2, 713 arg3, flags, msg, reply_received); 714 715 errno_t rc; 720 errno_t rc = ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, 721 (sysarg_t) iface, arg2, arg3, flags, msg); 722 if (rc != EOK) { 723 msg->retval = rc; 724 msg->done = true; 725 } 726 716 727 async_wait_for((aid_t) msg, &rc); 717 728 -
uspace/lib/c/generic/async/server.c
r87337dc5 rd054ad3 1088 1088 assert(call); 1089 1089 1090 if (call->flags & IPC_CALL_ANSWERED) 1090 if (call->flags & IPC_CALL_ANSWERED) { 1091 /* Answer to a call made by us. */ 1092 async_reply_received(call); 1091 1093 return; 1094 } 1092 1095 1093 1096 if (call->cap_handle == CAP_NIL) { … … 1195 1198 1196 1199 ipc_call_t call; 1197 errno_t rc = ipc_wait _cycle(&call, next_timeout, flags);1200 errno_t rc = ipc_wait(&call, next_timeout, flags); 1198 1201 1199 1202 atomic_dec(&threads_in_ipc_wait); -
uspace/lib/c/generic/ipc.c
r87337dc5 rd054ad3 50 50 #include <macros.h> 51 51 52 /**53 * Structures of this type are used for keeping track of sent asynchronous calls.54 */55 typedef struct async_call {56 ipc_async_callback_t callback;57 void *private;58 59 struct {60 ipc_call_t data;61 } msg;62 } async_call_t;63 64 /** Prologue for ipc_call_async_*() functions.65 *66 * @param private Argument for the answer/error callback.67 * @param callback Answer/error callback.68 *69 * @return New, partially initialized async_call structure or NULL.70 *71 */72 static inline async_call_t *ipc_prepare_async(void *private,73 ipc_async_callback_t callback)74 {75 async_call_t *call =76 (async_call_t *) malloc(sizeof(async_call_t));77 if (!call) {78 if (callback)79 callback(private, ENOMEM, NULL);80 81 return NULL;82 }83 84 call->callback = callback;85 call->private = private;86 87 return call;88 }89 90 /** Epilogue for ipc_call_async_*() functions.91 *92 * @param rc Value returned by the SYS_IPC_CALL_ASYNC_* syscall.93 * @param call Structure returned by ipc_prepare_async().94 */95 static inline void ipc_finish_async(errno_t rc, async_call_t *call)96 {97 if (!call) {98 /* Nothing to do regardless if failed or not */99 return;100 }101 102 if (rc != EOK) {103 /* Call asynchronous handler with error code */104 if (call->callback)105 call->callback(call->private, ENOENT, NULL);106 107 free(call);108 return;109 }110 }111 112 52 /** Fast asynchronous call. 113 53 * … … 126 66 * @param arg2 Service-defined payload argument. 127 67 * @param arg3 Service-defined payload argument. 128 * @param private Argument to be passed to the answer/error callback. 129 * @param callback Answer or error callback. 130 */ 131 void ipc_call_async_fast(cap_phone_handle_t phandle, sysarg_t imethod, 132 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, void *private, 133 ipc_async_callback_t callback) 134 { 135 async_call_t *call = ipc_prepare_async(private, callback); 136 if (!call) 137 return; 138 139 errno_t rc = (errno_t) __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, 68 * @param label A value to set to the label field of the answer. 69 */ 70 errno_t ipc_call_async_fast(cap_phone_handle_t phandle, sysarg_t imethod, 71 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, void *label) 72 { 73 return __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, 140 74 CAP_HANDLE_RAW(phandle), imethod, arg1, arg2, arg3, 141 (sysarg_t) call); 142 143 ipc_finish_async(rc, call); 75 (sysarg_t) label); 144 76 } 145 77 … … 159 91 * @param arg4 Service-defined payload argument. 160 92 * @param arg5 Service-defined payload argument. 161 * @param private Argument to be passed to the answer/error callback. 162 * @param callback Answer or error callback. 163 */ 164 void ipc_call_async_slow(cap_phone_handle_t phandle, sysarg_t imethod, 93 * @param label A value to set to the label field of the answer. 94 */ 95 errno_t ipc_call_async_slow(cap_phone_handle_t phandle, sysarg_t imethod, 165 96 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 166 void *private, ipc_async_callback_t callback) 167 { 168 async_call_t *call = ipc_prepare_async(private, callback); 169 if (!call) 170 return; 171 172 IPC_SET_IMETHOD(call->msg.data, imethod); 173 IPC_SET_ARG1(call->msg.data, arg1); 174 IPC_SET_ARG2(call->msg.data, arg2); 175 IPC_SET_ARG3(call->msg.data, arg3); 176 IPC_SET_ARG4(call->msg.data, arg4); 177 IPC_SET_ARG5(call->msg.data, arg5); 178 179 errno_t rc = (errno_t) __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW, 180 CAP_HANDLE_RAW(phandle), (sysarg_t) &call->msg.data, 181 (sysarg_t) call); 182 183 ipc_finish_async(rc, call); 97 void *label) 98 { 99 ipc_call_t data; 100 101 IPC_SET_IMETHOD(data, imethod); 102 IPC_SET_ARG1(data, arg1); 103 IPC_SET_ARG2(data, arg2); 104 IPC_SET_ARG3(data, arg3); 105 IPC_SET_ARG4(data, arg4); 106 IPC_SET_ARG5(data, arg5); 107 108 return __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW, 109 CAP_HANDLE_RAW(phandle), (sysarg_t) &data, 110 (sysarg_t) label); 184 111 } 185 112 … … 237 164 } 238 165 239 /** Handle received answer.240 *241 * @param data Call data of the answer.242 */243 static void handle_answer(ipc_call_t *data)244 {245 async_call_t *call = data->label;246 247 if (!call)248 return;249 250 if (call->callback)251 call->callback(call->private, IPC_GET_RETVAL(*data), data);252 free(call);253 }254 255 /** Wait for first IPC call to come.256 *257 * @param[out] call Storage for the received call.258 * @param[in] usec Timeout in microseconds259 * @param[in[ flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).260 *261 * @return Error code.262 */263 errno_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec, unsigned int flags)264 {265 errno_t rc = (errno_t) __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec,266 flags);267 268 /* Handle received answers */269 if ((rc == EOK) && (call->cap_handle == CAP_NIL) &&270 (call->flags & IPC_CALL_ANSWERED)) {271 handle_answer(call);272 }273 274 return rc;275 }276 277 166 /** Interrupt one thread of this task from waiting for IPC. 278 167 * … … 283 172 } 284 173 285 /** Wait for first IPC call to come. 286 * 287 * Only requests are returned, answers are processed internally. 288 * 289 * @param call Incoming call storage. 290 * @param usec Timeout in microseconds 291 * 292 * @return Error code. 293 * 294 */ 295 errno_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec) 296 { 297 errno_t rc; 298 299 do { 300 rc = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE); 301 } while ((rc == EOK) && (call->cap_handle == CAP_NIL) && 302 (call->flags & IPC_CALL_ANSWERED)); 303 304 return rc; 305 } 306 307 /** Check if there is an IPC call waiting to be picked up. 308 * 309 * Only requests are returned, answers are processed internally. 310 * 311 * @param call Incoming call storage. 312 * 313 * @return Error code. 314 * 315 */ 316 errno_t ipc_trywait_for_call(ipc_call_t *call) 317 { 318 errno_t rc; 319 320 do { 321 rc = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT, 322 SYNCH_FLAGS_NON_BLOCKING); 323 } while ((rc == EOK) && (call->cap_handle == CAP_NIL) && 324 (call->flags & IPC_CALL_ANSWERED)); 325 326 return rc; 174 errno_t ipc_wait(ipc_call_t *call, sysarg_t usec, unsigned int flags) 175 { 176 // TODO: Use expiration time instead of timeout. 177 return __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags); 327 178 } 328 179 -
uspace/lib/c/generic/private/async.h
r87337dc5 rd054ad3 143 143 extern async_port_handler_t async_get_port_handler(iface_t, port_id_t, void **); 144 144 145 extern void async_reply_received(ipc_call_t *); 146 145 147 #endif 146 148 -
uspace/lib/c/include/ipc/common.h
r87337dc5 rd054ad3 44 44 #define IPC_FLAG_BLOCKING 0x01 45 45 46 struct async_call;47 48 46 typedef struct { 49 47 sysarg_t args[IPC_CALL_LEN]; … … 51 49 sysarg_t in_phone_hash; 52 50 unsigned int flags; 53 struct async_call*label;51 void *label; 54 52 cap_call_handle_t cap_handle; 55 53 } ipc_call_t; -
uspace/lib/c/include/ipc/ipc.h
r87337dc5 rd054ad3 46 46 #include <abi/cap.h> 47 47 48 typedef void (*ipc_async_callback_t)(void *, errno_t, ipc_call_t *); 49 50 extern errno_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int); 48 extern errno_t ipc_wait(ipc_call_t *, sysarg_t, unsigned int); 51 49 extern void ipc_poke(void); 52 53 #define ipc_wait_for_call(data) \54 ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);55 56 extern errno_t ipc_wait_for_call_timeout(ipc_call_t *, sysarg_t);57 extern errno_t ipc_trywait_for_call(ipc_call_t *);58 50 59 51 /* … … 90 82 */ 91 83 92 #define ipc_call_async_0(phandle, method, private, callback) \ 93 ipc_call_async_fast((phandle), (method), 0, 0, 0, (private), (callback)) 94 #define ipc_call_async_1(phandle, method, arg1, private, callback) \ 95 ipc_call_async_fast((phandle), (method), (arg1), 0, 0, (private), \ 96 (callback)) 97 #define ipc_call_async_2(phandle, method, arg1, arg2, private, callback) \ 98 ipc_call_async_fast((phandle), (method), (arg1), (arg2), 0, \ 99 (private), (callback)) 100 #define ipc_call_async_3(phandle, method, arg1, arg2, arg3, private, callback) \ 84 #define ipc_call_async_0(phandle, method, label) \ 85 ipc_call_async_fast((phandle), (method), 0, 0, 0, (label)) 86 #define ipc_call_async_1(phandle, method, arg1, label) \ 87 ipc_call_async_fast((phandle), (method), (arg1), 0, 0, (label)) 88 #define ipc_call_async_2(phandle, method, arg1, arg2, label) \ 89 ipc_call_async_fast((phandle), (method), (arg1), (arg2), 0, (label)) 90 #define ipc_call_async_3(phandle, method, arg1, arg2, arg3, label) \ 101 91 ipc_call_async_fast((phandle), (method), (arg1), (arg2), (arg3), \ 102 (private), (callback)) 103 #define ipc_call_async_4(phandle, method, arg1, arg2, arg3, arg4, private, \ 104 callback) \ 92 (label)) 93 #define ipc_call_async_4(phandle, method, arg1, arg2, arg3, arg4, label) \ 105 94 ipc_call_async_slow((phandle), (method), (arg1), (arg2), (arg3), \ 106 (arg4), 0, ( private), (callback))95 (arg4), 0, (label)) 107 96 #define ipc_call_async_5(phandle, method, arg1, arg2, arg3, arg4, arg5, \ 108 private, callback) \97 label) \ 109 98 ipc_call_async_slow((phandle), (method), (arg1), (arg2), (arg3), \ 110 (arg4), (arg5), ( private), (callback))99 (arg4), (arg5), (label)) 111 100 112 extern voidipc_call_async_fast(cap_phone_handle_t, sysarg_t, sysarg_t,113 sysarg_t, sysarg_t, void * , ipc_async_callback_t);114 extern voidipc_call_async_slow(cap_phone_handle_t, sysarg_t, sysarg_t,115 sysarg_t, sysarg_t, sysarg_t, sysarg_t, void * , ipc_async_callback_t);101 extern errno_t ipc_call_async_fast(cap_phone_handle_t, sysarg_t, sysarg_t, 102 sysarg_t, sysarg_t, void *); 103 extern errno_t ipc_call_async_slow(cap_phone_handle_t, sysarg_t, sysarg_t, 104 sysarg_t, sysarg_t, sysarg_t, sysarg_t, void *); 116 105 117 106 extern errno_t ipc_hangup(cap_phone_handle_t);
Note:
See TracChangeset
for help on using the changeset viewer.