Changeset 19f24fd in mainline for uspace/lib/libc/generic/async.c
- Timestamp:
- 2010-02-05T22:25:52Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dafa2d04
- Parents:
- 83349b03 (diff), d42976c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/async.c
r83349b03 r19f24fd 1287 1287 } 1288 1288 1289 /** Wrapper for forwarding any read request 1290 * 1291 * 1292 */ 1293 int async_data_read_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, 1294 ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) 1295 { 1296 ipc_callid_t callid; 1297 if (!async_data_read_receive(&callid, NULL)) { 1298 ipc_answer_0(callid, EINVAL); 1299 return EINVAL; 1300 } 1301 1302 aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4, 1303 dataptr); 1304 if (msg == 0) { 1305 ipc_answer_0(callid, EINVAL); 1306 return EINVAL; 1307 } 1308 1309 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0, 1310 IPC_FF_ROUTE_FROM_ME); 1311 if (retval != EOK) { 1312 ipc_answer_0(callid, retval); 1313 return retval; 1314 } 1315 1316 ipcarg_t rc; 1317 async_wait_for(msg, &rc); 1318 1319 return (int) rc; 1320 } 1321 1289 1322 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1290 1323 * 1291 * @param phoneid Phone that will be used to contact the receiving side. 1292 * @param src Address of the beginning of the source buffer. 1293 * @param size Size of the source buffer. 1294 * 1295 * @return Zero on success or a negative error code from errno.h. 1324 * @param phoneid Phone that will be used to contact the receiving side. 1325 * @param src Address of the beginning of the source buffer. 1326 * @param size Size of the source buffer. 1327 * 1328 * @return Zero on success or a negative error code from errno.h. 1329 * 1296 1330 */ 1297 1331 int async_data_write_start(int phoneid, const void *src, size_t size) … … 1308 1342 * So far, this wrapper is to be used from within a connection fibril. 1309 1343 * 1310 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1311 * be stored. 1312 * @param size Storage where the suggested size will be stored. May be 1313 * NULL 1314 * 1315 * @return Non-zero on success, zero on failure. 1344 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1345 * be stored. 1346 * @param size Storage where the suggested size will be stored. May be 1347 * NULL 1348 * 1349 * @return Non-zero on success, zero on failure. 1350 * 1316 1351 */ 1317 1352 int async_data_write_receive(ipc_callid_t *callid, size_t *size) … … 1320 1355 1321 1356 assert(callid); 1322 1357 1323 1358 *callid = async_get_call(&data); 1324 1359 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE) 1325 1360 return 0; 1361 1326 1362 if (size) 1327 1363 *size = (size_t) IPC_GET_ARG2(data); 1364 1328 1365 return 1; 1329 1366 } … … 1334 1371 * so that the user doesn't have to remember the meaning of each IPC argument. 1335 1372 * 1336 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1337 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 1338 * @param size Final size for the IPC_M_DATA_WRITE call. 1339 * 1340 * @return Zero on success or a value from @ref errno.h on failure. 1373 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1374 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 1375 * @param size Final size for the IPC_M_DATA_WRITE call. 1376 * 1377 * @return Zero on success or a value from @ref errno.h on failure. 1378 * 1341 1379 */ 1342 1380 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) … … 1345 1383 } 1346 1384 1347 /** Wrapper for receiving b lobs via the async_data_write_*1385 /** Wrapper for receiving binary data or strings 1348 1386 * 1349 1387 * This wrapper only makes it more comfortable to use async_data_write_* 1350 * functions to receive blobs. 1351 * 1352 * @param blob Pointer to data pointer (which should be later disposed 1353 * by free()). If the operation fails, the pointer is not 1354 * touched. 1355 * @param max_size Maximum size (in bytes) of the blob to receive. 0 means 1356 * no limit. 1357 * @param received If not NULL, the size of the received data is stored here. 1388 * functions to receive binary data or strings. 1389 * 1390 * @param data Pointer to data pointer (which should be later disposed 1391 * by free()). If the operation fails, the pointer is not 1392 * touched. 1393 * @param nullterm If true then the received data is always zero terminated. 1394 * This also causes to allocate one extra byte beyond the 1395 * raw transmitted data. 1396 * @param min_size Minimum size (in bytes) of the data to receive. 1397 * @param max_size Maximum size (in bytes) of the data to receive. 0 means 1398 * no limit. 1399 * @param granulariy If non-zero then the size of the received data has to 1400 * be divisible by this value. 1401 * @param received If not NULL, the size of the received data is stored here. 1358 1402 * 1359 1403 * @return Zero on success or a value from @ref errno.h on failure. 1360 1404 * 1361 1405 */ 1362 int async_data_blob_receive(char **blob, const size_t max_size, size_t *received) 1406 int async_data_write_accept(void **data, const bool nullterm, 1407 const size_t min_size, const size_t max_size, const size_t granularity, 1408 size_t *received) 1363 1409 { 1364 1410 ipc_callid_t callid; … … 1369 1415 } 1370 1416 1417 if (size < min_size) { 1418 ipc_answer_0(callid, EINVAL); 1419 return EINVAL; 1420 } 1421 1371 1422 if ((max_size > 0) && (size > max_size)) { 1372 1423 ipc_answer_0(callid, EINVAL); … … 1374 1425 } 1375 1426 1376 char *data = (char *) malloc(size); 1377 if (data == NULL) { 1427 if ((granularity > 0) && ((size % granularity) != 0)) { 1428 ipc_answer_0(callid, EINVAL); 1429 return EINVAL; 1430 } 1431 1432 void *_data; 1433 1434 if (nullterm) 1435 _data = malloc(size + 1); 1436 else 1437 _data = malloc(size); 1438 1439 if (_data == NULL) { 1378 1440 ipc_answer_0(callid, ENOMEM); 1379 1441 return ENOMEM; 1380 1442 } 1381 1443 1382 int rc = async_data_write_finalize(callid, data, size);1444 int rc = async_data_write_finalize(callid, _data, size); 1383 1445 if (rc != EOK) { 1384 free( data);1446 free(_data); 1385 1447 return rc; 1386 1448 } 1387 1449 1388 *blob = data; 1450 if (nullterm) 1451 ((char *) _data)[size] = 0; 1452 1453 *data = _data; 1389 1454 if (received != NULL) 1390 1455 *received = size; … … 1393 1458 } 1394 1459 1395 /** Wrapper for receiving strings via the async_data_write_* 1396 * 1397 * This wrapper only makes it more comfortable to use async_data_write_* 1398 * functions to receive strings. 1399 * 1400 * @param str Pointer to string pointer (which should be later disposed 1401 * by free()). If the operation fails, the pointer is not 1402 * touched. 1403 * @param max_size Maximum size (in bytes) of the string to receive. 0 means 1404 * no limit. 1405 * 1406 * @return Zero on success or a value from @ref errno.h on failure. 1407 * 1408 */ 1409 int async_data_string_receive(char **str, const size_t max_size) 1460 /** Wrapper for voiding any data that is about to be received 1461 * 1462 * This wrapper can be used to void any pending data 1463 * 1464 * @param retval Error value from @ref errno.h to be returned to the caller. 1465 * 1466 */ 1467 void async_data_write_void(const int retval) 1410 1468 { 1411 1469 ipc_callid_t callid; 1412 size_t size; 1413 if (!async_data_write_receive(&callid, &size)) { 1470 async_data_write_receive(&callid, NULL); 1471 ipc_answer_0(callid, retval); 1472 } 1473 1474 /** Wrapper for forwarding any data that is about to be received 1475 * 1476 * 1477 */ 1478 int async_data_write_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, 1479 ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) 1480 { 1481 ipc_callid_t callid; 1482 if (!async_data_write_receive(&callid, NULL)) { 1414 1483 ipc_answer_0(callid, EINVAL); 1415 1484 return EINVAL; 1416 1485 } 1417 1486 1418 if ((max_size > 0) && (size > max_size)) { 1487 aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4, 1488 dataptr); 1489 if (msg == 0) { 1419 1490 ipc_answer_0(callid, EINVAL); 1420 1491 return EINVAL; 1421 1492 } 1422 1493 1423 char *data = (char *) malloc(size + 1); 1424 if (data == NULL) { 1425 ipc_answer_0(callid, ENOMEM); 1426 return ENOMEM; 1427 } 1428 1429 int rc = async_data_write_finalize(callid, data, size); 1430 if (rc != EOK) { 1431 free(data); 1432 return rc; 1433 } 1434 1435 data[size] = 0; 1436 *str = data; 1437 return EOK; 1494 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0, 1495 IPC_FF_ROUTE_FROM_ME); 1496 if (retval != EOK) { 1497 ipc_answer_0(callid, retval); 1498 return retval; 1499 } 1500 1501 ipcarg_t rc; 1502 async_wait_for(msg, &rc); 1503 1504 return (int) rc; 1438 1505 } 1439 1506
Note:
See TracChangeset
for help on using the changeset viewer.