Changes in uspace/lib/libc/generic/async.c [0da4e41:8619f25] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/async.c
r0da4e41 r8619f25 83 83 * 84 84 * callid = async_get_call(&call); 85 * somehow_handle_the_call(callid, call);85 * handle_call(callid, call); 86 86 * ipc_answer_2(callid, 1, 2, 3); 87 87 * … … 94 94 #include <futex.h> 95 95 #include <async.h> 96 #include <async_priv.h>97 96 #include <fibril.h> 98 97 #include <stdio.h> … … 111 110 atomic_t threads_in_ipc_wait = { 0 }; 112 111 112 /** Structures of this type represent a waiting fibril. */ 113 typedef struct { 114 /** Expiration time. */ 115 struct timeval expires; 116 117 /** If true, this struct is in the timeout list. */ 118 bool inlist; 119 120 /** Timeout list link. */ 121 link_t link; 122 123 /** Identification of and link to the waiting fibril. */ 124 fid_t fid; 125 126 /** If true, this fibril is currently active. */ 127 bool active; 128 129 /** If true, we have timed out. */ 130 bool timedout; 131 } awaiter_t; 132 113 133 typedef struct { 114 134 awaiter_t wdata; … … 233 253 * 234 254 */ 235 void async_insert_timeout(awaiter_t *wd)236 { 237 wd->t o_event.occurred= false;238 wd-> to_event.inlist = true;255 static void insert_timeout(awaiter_t *wd) 256 { 257 wd->timedout = false; 258 wd->inlist = true; 239 259 240 260 link_t *tmp = timeout_list.next; 241 261 while (tmp != &timeout_list) { 242 awaiter_t *cur; 243 244 cur = list_get_instance(tmp, awaiter_t, to_event.link); 245 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 262 awaiter_t *cur = list_get_instance(tmp, awaiter_t, link); 263 264 if (tv_gteq(&cur->expires, &wd->expires)) 246 265 break; 266 247 267 tmp = tmp->next; 248 268 } 249 269 250 list_append(&wd-> to_event.link, tmp);270 list_append(&wd->link, tmp); 251 271 } 252 272 … … 295 315 296 316 /* If in timeout list, remove it */ 297 if (conn->wdata. to_event.inlist) {298 conn->wdata. to_event.inlist = false;299 list_remove(&conn->wdata. to_event.link);317 if (conn->wdata.inlist) { 318 conn->wdata.inlist = false; 319 list_remove(&conn->wdata.link); 300 320 } 301 321 … … 385 405 386 406 if (usecs) { 387 gettimeofday(&conn->wdata. to_event.expires, NULL);388 tv_add(&conn->wdata. to_event.expires, usecs);407 gettimeofday(&conn->wdata.expires, NULL); 408 tv_add(&conn->wdata.expires, usecs); 389 409 } else 390 conn->wdata. to_event.inlist = false;410 conn->wdata.inlist = false; 391 411 392 412 /* If nothing in queue, wait until something arrives */ 393 413 while (list_empty(&conn->msg_queue)) { 394 414 if (usecs) 395 async_insert_timeout(&conn->wdata);415 insert_timeout(&conn->wdata); 396 416 397 417 conn->wdata.active = false; … … 410 430 */ 411 431 futex_down(&async_futex); 412 if ((usecs) && (conn->wdata.t o_event.occurred)432 if ((usecs) && (conn->wdata.timedout) 413 433 && (list_empty(&conn->msg_queue))) { 414 434 /* If we timed out -> exit */ … … 605 625 link_t *cur = timeout_list.next; 606 626 while (cur != &timeout_list) { 607 awaiter_t *waiter; 608 609 waiter = list_get_instance(cur, awaiter_t, to_event.link); 610 if (tv_gt(&waiter->to_event.expires, &tv)) 627 awaiter_t *waiter = list_get_instance(cur, awaiter_t, link); 628 629 if (tv_gt(&waiter->expires, &tv)) 611 630 break; 612 631 613 632 cur = cur->next; 614 615 list_remove(&waiter-> to_event.link);616 waiter-> to_event.inlist = false;617 waiter->t o_event.occurred= true;633 634 list_remove(&waiter->link); 635 waiter->inlist = false; 636 waiter->timedout = true; 618 637 619 638 /* … … 652 671 if (!list_empty(&timeout_list)) { 653 672 awaiter_t *waiter = list_get_instance(timeout_list.next, 654 awaiter_t, to_event.link);673 awaiter_t, link); 655 674 656 675 struct timeval tv; 657 676 gettimeofday(&tv, NULL); 658 677 659 if (tv_gteq(&tv, &waiter-> to_event.expires)) {678 if (tv_gteq(&tv, &waiter->expires)) { 660 679 futex_up(&async_futex); 661 680 handle_expired_timeouts(); 662 681 continue; 663 682 } else 664 timeout = tv_sub(&waiter->to_event.expires, 665 &tv); 683 timeout = tv_sub(&waiter->expires, &tv); 666 684 } else 667 685 timeout = SYNCH_NO_TIMEOUT; … … 764 782 765 783 /* Remove message from timeout list */ 766 if (msg->wdata. to_event.inlist)767 list_remove(&msg->wdata. to_event.link);784 if (msg->wdata.inlist) 785 list_remove(&msg->wdata.link); 768 786 769 787 msg->done = true; … … 804 822 msg->dataptr = dataptr; 805 823 806 msg->wdata. to_event.inlist = false;824 msg->wdata.inlist = false; 807 825 /* We may sleep in the next method, but it will use its own mechanism */ 808 826 msg->wdata.active = true; … … 844 862 msg->dataptr = dataptr; 845 863 846 msg->wdata. to_event.inlist = false;864 msg->wdata.inlist = false; 847 865 /* We may sleep in next method, but it will use its own mechanism */ 848 866 msg->wdata.active = true; … … 873 891 msg->wdata.fid = fibril_get_id(); 874 892 msg->wdata.active = false; 875 msg->wdata. to_event.inlist = false;893 msg->wdata.inlist = false; 876 894 877 895 /* Leave the async_futex locked when entering this function */ … … 911 929 } 912 930 913 gettimeofday(&msg->wdata. to_event.expires, NULL);914 tv_add(&msg->wdata. to_event.expires, timeout);931 gettimeofday(&msg->wdata.expires, NULL); 932 tv_add(&msg->wdata.expires, timeout); 915 933 916 934 msg->wdata.fid = fibril_get_id(); 917 935 msg->wdata.active = false; 918 async_insert_timeout(&msg->wdata);936 insert_timeout(&msg->wdata); 919 937 920 938 /* Leave the async_futex locked when entering this function */ … … 952 970 msg->wdata.active = false; 953 971 954 gettimeofday(&msg->wdata. to_event.expires, NULL);955 tv_add(&msg->wdata. to_event.expires, timeout);972 gettimeofday(&msg->wdata.expires, NULL); 973 tv_add(&msg->wdata.expires, timeout); 956 974 957 975 futex_down(&async_futex); 958 976 959 async_insert_timeout(&msg->wdata);977 insert_timeout(&msg->wdata); 960 978 961 979 /* Leave the async_futex locked when entering this function */ … … 1087 1105 } 1088 1106 1089 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework.1090 *1091 * @param phoneid Phone that will be used to contact the receiving side.1092 * @param dst Destination address space area base.1093 * @param size Size of the destination address space area.1094 * @param arg User defined argument.1095 * @param flags Storage where the received flags will be stored. Can be1096 * NULL.1097 *1098 * @return Zero on success or a negative error code from errno.h.1099 */1100 int async_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg,1101 int *flags)1102 {1103 int res;1104 sysarg_t tmp_flags;1105 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,1106 (ipcarg_t) size, arg, NULL, &tmp_flags);1107 if (flags)1108 *flags = tmp_flags;1109 return res;1110 }1111 1112 /** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework.1113 *1114 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls1115 * so that the user doesn't have to remember the meaning of each IPC argument.1116 *1117 * So far, this wrapper is to be used from within a connection fibril.1118 *1119 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will1120 * be stored.1121 * @param size Destination address space area size.1122 *1123 * @return Non-zero on success, zero on failure.1124 */1125 int async_share_in_receive(ipc_callid_t *callid, size_t *size)1126 {1127 ipc_call_t data;1128 1129 assert(callid);1130 assert(size);1131 1132 *callid = async_get_call(&data);1133 if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)1134 return 0;1135 *size = (size_t) IPC_GET_ARG2(data);1136 return 1;1137 }1138 1139 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.1140 *1141 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls1142 * so that the user doesn't have to remember the meaning of each IPC argument.1143 *1144 * @param callid Hash of the IPC_M_DATA_READ call to answer.1145 * @param src Source address space base.1146 * @param flags Flags to be used for sharing. Bits can be only cleared.1147 *1148 * @return Zero on success or a value from @ref errno.h on failure.1149 */1150 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags)1151 {1152 return ipc_share_in_finalize(callid, src, flags);1153 }1154 1155 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework.1156 *1157 * @param phoneid Phone that will be used to contact the receiving side.1158 * @param src Source address space area base address.1159 * @param flags Flags to be used for sharing. Bits can be only cleared.1160 *1161 * @return Zero on success or a negative error code from errno.h.1162 */1163 int async_share_out_start(int phoneid, void *src, int flags)1164 {1165 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,1166 (ipcarg_t) flags);1167 }1168 1169 /** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework.1170 *1171 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls1172 * so that the user doesn't have to remember the meaning of each IPC argument.1173 *1174 * So far, this wrapper is to be used from within a connection fibril.1175 *1176 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will1177 * be stored.1178 * @param size Storage where the source address space area size will be1179 * stored.1180 * @param flags Storage where the sharing flags will be stored.1181 *1182 * @return Non-zero on success, zero on failure.1183 */1184 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)1185 {1186 ipc_call_t data;1187 1188 assert(callid);1189 assert(size);1190 assert(flags);1191 1192 *callid = async_get_call(&data);1193 if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)1194 return 0;1195 *size = (size_t) IPC_GET_ARG2(data);1196 *flags = (int) IPC_GET_ARG3(data);1197 return 1;1198 }1199 1200 /** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework.1201 *1202 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls1203 * so that the user doesn't have to remember the meaning of each IPC argument.1204 *1205 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.1206 * @param dst Destination address space area base address.1207 *1208 * @return Zero on success or a value from @ref errno.h on failure.1209 */1210 int async_share_out_finalize(ipc_callid_t callid, void *dst)1211 {1212 return ipc_share_out_finalize(callid, dst);1213 }1214 1215 1216 /** Wrapper for making IPC_M_DATA_READ calls using the async framework.1217 *1218 * @param phoneid Phone that will be used to contact the receiving side.1219 * @param dst Address of the beginning of the destination buffer.1220 * @param size Size of the destination buffer.1221 *1222 * @return Zero on success or a negative error code from errno.h.1223 */1224 int async_data_read_start(int phoneid, void *dst, size_t size)1225 {1226 return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,1227 (ipcarg_t) size);1228 }1229 1230 /** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.1231 *1232 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls1233 * so that the user doesn't have to remember the meaning of each IPC argument.1234 *1235 * So far, this wrapper is to be used from within a connection fibril.1236 *1237 * @param callid Storage where the hash of the IPC_M_DATA_READ call will1238 * be stored.1239 * @param size Storage where the maximum size will be stored. Can be1240 * NULL.1241 *1242 * @return Non-zero on success, zero on failure.1243 */1244 int async_data_read_receive(ipc_callid_t *callid, size_t *size)1245 {1246 ipc_call_t data;1247 1248 assert(callid);1249 1250 *callid = async_get_call(&data);1251 if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)1252 return 0;1253 if (size)1254 *size = (size_t) IPC_GET_ARG2(data);1255 return 1;1256 }1257 1258 /** Wrapper for answering the IPC_M_DATA_READ calls using the async framework.1259 *1260 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls1261 * so that the user doesn't have to remember the meaning of each IPC argument.1262 *1263 * @param callid Hash of the IPC_M_DATA_READ call to answer.1264 * @param src Source address for the IPC_M_DATA_READ call.1265 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than1266 * the maximum size announced by the sender.1267 *1268 * @return Zero on success or a value from @ref errno.h on failure.1269 */1270 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)1271 {1272 return ipc_data_read_finalize(callid, src, size);1273 }1274 1275 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.1276 *1277 * @param phoneid Phone that will be used to contact the receiving side.1278 * @param src Address of the beginning of the source buffer.1279 * @param size Size of the source buffer.1280 *1281 * @return Zero on success or a negative error code from errno.h.1282 */1283 int async_data_write_start(int phoneid, const void *src, size_t size)1284 {1285 return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,1286 (ipcarg_t) size);1287 }1288 1289 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.1290 *1291 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls1292 * so that the user doesn't have to remember the meaning of each IPC argument.1293 *1294 * So far, this wrapper is to be used from within a connection fibril.1295 *1296 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will1297 * be stored.1298 * @param size Storage where the suggested size will be stored. May be1299 * NULL1300 *1301 * @return Non-zero on success, zero on failure.1302 */1303 int async_data_write_receive(ipc_callid_t *callid, size_t *size)1304 {1305 ipc_call_t data;1306 1307 assert(callid);1308 1309 *callid = async_get_call(&data);1310 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)1311 return 0;1312 if (size)1313 *size = (size_t) IPC_GET_ARG2(data);1314 return 1;1315 }1316 1317 /** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework.1318 *1319 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls1320 * so that the user doesn't have to remember the meaning of each IPC argument.1321 *1322 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.1323 * @param dst Final destination address for the IPC_M_DATA_WRITE call.1324 * @param size Final size for the IPC_M_DATA_WRITE call.1325 *1326 * @return Zero on success or a value from @ref errno.h on failure.1327 */1328 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)1329 {1330 return ipc_data_write_finalize(callid, dst, size);1331 }1332 1333 1107 /** @} 1334 1108 */
Note:
See TracChangeset
for help on using the changeset viewer.