Changes in uspace/lib/c/generic/async.c [f302586:ab9f443] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
rf302586 rab9f443 189 189 /** If reply was received. */ 190 190 bool done; 191 192 /** If the message / reply should be discarded on arrival. */ 193 bool forget; 194 195 /** If already destroyed. */ 196 bool destroyed; 191 197 192 198 /** Pointer to where the answer data is stored. */ … … 240 246 /** Identifier of the incoming connection handled by the current fibril. */ 241 247 static fibril_local connection_t *fibril_connection; 248 249 static void to_event_initialize(to_event_t *to) 250 { 251 struct timeval tv = { 0 }; 252 253 to->inlist = false; 254 to->occurred = false; 255 link_initialize(&to->link); 256 to->expires = tv; 257 } 258 259 static void wu_event_initialize(wu_event_t *wu) 260 { 261 wu->inlist = false; 262 link_initialize(&wu->link); 263 } 264 265 void awaiter_initialize(awaiter_t *aw) 266 { 267 aw->fid = 0; 268 aw->active = false; 269 to_event_initialize(&aw->to_event); 270 wu_event_initialize(&aw->wu_event); 271 } 272 273 static amsg_t *amsg_create(void) 274 { 275 amsg_t *msg; 276 277 msg = malloc(sizeof(amsg_t)); 278 if (msg) { 279 msg->done = false; 280 msg->forget = false; 281 msg->destroyed = false; 282 msg->dataptr = NULL; 283 msg->retval = (sysarg_t) EINVAL; 284 awaiter_initialize(&msg->wdata); 285 } 286 287 return msg; 288 } 289 290 static void amsg_destroy(amsg_t *msg) 291 { 292 assert(!msg->destroyed); 293 msg->destroyed = true; 294 free(msg); 295 } 242 296 243 297 static void *default_client_data_constructor(void) … … 1100 1154 1101 1155 msg->done = true; 1102 if (!msg->wdata.active) { 1156 1157 if (msg->forget) { 1158 assert(msg->wdata.active); 1159 amsg_destroy(msg); 1160 } else if (!msg->wdata.active) { 1103 1161 msg->wdata.active = true; 1104 1162 fibril_add_ready(msg->wdata.fid); 1105 1163 } 1106 1164 1107 1165 futex_up(&async_futex); 1108 1166 } … … 1131 1189 return 0; 1132 1190 1133 amsg_t *msg = malloc(sizeof(amsg_t));1191 amsg_t *msg = amsg_create(); 1134 1192 if (msg == NULL) 1135 1193 return 0; 1136 1194 1137 msg->done = false;1138 1195 msg->dataptr = dataptr; 1139 1140 msg->wdata.to_event.inlist = false;1141 1142 /*1143 * We may sleep in the next method,1144 * but it will use its own means1145 */1146 1196 msg->wdata.active = true; 1147 1197 … … 1177 1227 return 0; 1178 1228 1179 amsg_t *msg = malloc(sizeof(amsg_t)); 1180 1229 amsg_t *msg = amsg_create(); 1181 1230 if (msg == NULL) 1182 1231 return 0; 1183 1232 1184 msg->done = false;1185 1233 msg->dataptr = dataptr; 1186 1187 msg->wdata.to_event.inlist = false;1188 1189 /*1190 * We may sleep in the next method,1191 * but it will use its own means1192 */1193 1234 msg->wdata.active = true; 1194 1235 … … 1213 1254 1214 1255 futex_down(&async_futex); 1256 1257 assert(!msg->forget); 1258 assert(!msg->destroyed); 1259 1215 1260 if (msg->done) { 1216 1261 futex_up(&async_futex); … … 1231 1276 *retval = msg->retval; 1232 1277 1233 free(msg);1278 amsg_destroy(msg); 1234 1279 } 1235 1280 1236 1281 /** Wait for a message sent by the async framework, timeout variant. 1282 * 1283 * If the wait times out, the caller may choose to either wait again by calling 1284 * async_wait_for() or async_wait_timeout(), or forget the message via 1285 * async_forget(). 1237 1286 * 1238 1287 * @param amsgid Hash of the message to wait for. … … 1255 1304 1256 1305 futex_down(&async_futex); 1306 1307 assert(!msg->forget); 1308 assert(!msg->destroyed); 1309 1257 1310 if (msg->done) { 1258 1311 futex_up(&async_futex); … … 1279 1332 *retval = msg->retval; 1280 1333 1281 free(msg);1334 amsg_destroy(msg); 1282 1335 1283 1336 return 0; 1284 1337 } 1338 1339 /** Discard the message / reply on arrival. 1340 * 1341 * The message will be marked to be discarded once the reply arrives in 1342 * reply_received(). It is not allowed to call async_wait_for() or 1343 * async_wait_timeout() on this message after a call to this function. 1344 * 1345 * @param amsgid Hash of the message to forget. 1346 */ 1347 void async_forget(aid_t amsgid) 1348 { 1349 amsg_t *msg = (amsg_t *) amsgid; 1350 1351 assert(msg); 1352 assert(!msg->forget); 1353 assert(!msg->destroyed); 1354 1355 futex_down(&async_futex); 1356 if (msg->done) 1357 amsg_destroy(msg); 1358 else 1359 msg->forget = true; 1360 futex_up(&async_futex); 1361 } 1285 1362 1286 1363 /** Wait for specified time. … … 1293 1370 void async_usleep(suseconds_t timeout) 1294 1371 { 1295 amsg_t *msg = malloc(sizeof(amsg_t)); 1296 1372 amsg_t *msg = amsg_create(); 1297 1373 if (!msg) 1298 1374 return; 1299 1375 1300 1376 msg->wdata.fid = fibril_get_id(); 1301 msg->wdata.active = false;1302 1377 1303 1378 gettimeofday(&msg->wdata.to_event.expires, NULL); … … 1313 1388 /* Futex is up automatically after fibril_switch() */ 1314 1389 1315 free(msg);1390 amsg_destroy(msg); 1316 1391 } 1317 1392 … … 1584 1659 ipc_call_t result; 1585 1660 1586 amsg_t *msg = malloc(sizeof(amsg_t));1587 if ( msg == NULL) {1661 amsg_t *msg = amsg_create(); 1662 if (!msg) { 1588 1663 free(sess); 1589 1664 errno = ENOMEM; … … 1591 1666 } 1592 1667 1593 msg->done = false;1594 1668 msg->dataptr = &result; 1595 1596 msg->wdata.to_event.inlist = false;1597 1598 /*1599 * We may sleep in the next method,1600 * but it will use its own means1601 */1602 1669 msg->wdata.active = true; 1603 1670 … … 1643 1710 ipc_call_t result; 1644 1711 1645 amsg_t *msg = malloc(sizeof(amsg_t));1646 if ( msg == NULL)1712 amsg_t *msg = amsg_create(); 1713 if (!msg) 1647 1714 return ENOENT; 1648 1715 1649 msg->done = false;1650 1716 msg->dataptr = &result; 1651 1652 msg->wdata.to_event.inlist = false;1653 1654 /*1655 * We may sleep in the next method,1656 * but it will use its own means1657 */1658 1717 msg->wdata.active = true; 1659 1718 … … 2251 2310 IPC_FF_ROUTE_FROM_ME); 2252 2311 if (retval != EOK) { 2253 async_ wait_for(msg, NULL);2312 async_forget(msg); 2254 2313 ipc_answer_0(callid, retval); 2255 2314 return retval; … … 2445 2504 IPC_FF_ROUTE_FROM_ME); 2446 2505 if (retval != EOK) { 2447 async_ wait_for(msg, NULL);2506 async_forget(msg); 2448 2507 ipc_answer_0(callid, retval); 2449 2508 return retval;
Note:
See TracChangeset
for help on using the changeset viewer.