Changeset 5cde90f in mainline for uspace/lib/libc/generic/async.c


Ignore:
Timestamp:
2010-02-19T17:16:46Z (14 years ago)
Author:
Pavel Rimsky <pavel@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
617652f
Parents:
b86d436 (diff), f41aa81 (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.
Message:

Synchronizing with head (which has just been synchronized with this branch).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/async.c

    rb86d436 r5cde90f  
    12871287}
    12881288
     1289/** Wrapper for forwarding any read request
     1290 *
     1291 *
     1292 */
     1293int 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                async_wait_for(msg, NULL);
     1313                ipc_answer_0(callid, retval);
     1314                return retval;
     1315        }
     1316       
     1317        ipcarg_t rc;
     1318        async_wait_for(msg, &rc);
     1319       
     1320        return (int) rc;
     1321}
     1322
    12891323/** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
    12901324 *
    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.
     1325 * @param phoneid Phone that will be used to contact the receiving side.
     1326 * @param src     Address of the beginning of the source buffer.
     1327 * @param size    Size of the source buffer.
     1328 *
     1329 * @return Zero on success or a negative error code from errno.h.
     1330 *
    12961331 */
    12971332int async_data_write_start(int phoneid, const void *src, size_t size)
     
    13081343 * So far, this wrapper is to be used from within a connection fibril.
    13091344 *
    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.
     1345 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
     1346 *               be stored.
     1347 * @param size   Storage where the suggested size will be stored. May be
     1348 *               NULL
     1349 *
     1350 * @return Non-zero on success, zero on failure.
     1351 *
    13161352 */
    13171353int async_data_write_receive(ipc_callid_t *callid, size_t *size)
     
    13201356       
    13211357        assert(callid);
    1322 
     1358       
    13231359        *callid = async_get_call(&data);
    13241360        if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
    13251361                return 0;
     1362       
    13261363        if (size)
    13271364                *size = (size_t) IPC_GET_ARG2(data);
     1365       
    13281366        return 1;
    13291367}
     
    13341372 * so that the user doesn't have to remember the meaning of each IPC argument.
    13351373 *
    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.
     1374 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     1375 * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
     1376 * @param size   Final size for the IPC_M_DATA_WRITE call.
     1377 *
     1378 * @return Zero on success or a value from @ref errno.h on failure.
     1379 *
    13411380 */
    13421381int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
     
    13451384}
    13461385
    1347 /** Wrapper for receiving blobs via the async_data_write_*
     1386/** Wrapper for receiving binary data or strings
    13481387 *
    13491388 * 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.
     1389 * functions to receive binary data or strings.
     1390 *
     1391 * @param data       Pointer to data pointer (which should be later disposed
     1392 *                   by free()). If the operation fails, the pointer is not
     1393 *                   touched.
     1394 * @param nullterm   If true then the received data is always zero terminated.
     1395 *                   This also causes to allocate one extra byte beyond the
     1396 *                   raw transmitted data.
     1397 * @param min_size   Minimum size (in bytes) of the data to receive.
     1398 * @param max_size   Maximum size (in bytes) of the data to receive. 0 means
     1399 *                   no limit.
     1400 * @param granulariy If non-zero then the size of the received data has to
     1401 *                   be divisible by this value.
     1402 * @param received   If not NULL, the size of the received data is stored here.
    13581403 *
    13591404 * @return Zero on success or a value from @ref errno.h on failure.
    13601405 *
    13611406 */
    1362 int async_data_blob_receive(char **blob, const size_t max_size, size_t *received)
     1407int async_data_write_accept(void **data, const bool nullterm,
     1408    const size_t min_size, const size_t max_size, const size_t granularity,
     1409    size_t *received)
    13631410{
    13641411        ipc_callid_t callid;
     
    13691416        }
    13701417       
     1418        if (size < min_size) {
     1419                ipc_answer_0(callid, EINVAL);
     1420                return EINVAL;
     1421        }
     1422       
    13711423        if ((max_size > 0) && (size > max_size)) {
    13721424                ipc_answer_0(callid, EINVAL);
     
    13741426        }
    13751427       
    1376         char *data = (char *) malloc(size);
    1377         if (data == NULL) {
     1428        if ((granularity > 0) && ((size % granularity) != 0)) {
     1429                ipc_answer_0(callid, EINVAL);
     1430                return EINVAL;
     1431        }
     1432       
     1433        void *_data;
     1434       
     1435        if (nullterm)
     1436                _data = malloc(size + 1);
     1437        else
     1438                _data = malloc(size);
     1439       
     1440        if (_data == NULL) {
    13781441                ipc_answer_0(callid, ENOMEM);
    13791442                return ENOMEM;
    13801443        }
    13811444       
    1382         int rc = async_data_write_finalize(callid, data, size);
     1445        int rc = async_data_write_finalize(callid, _data, size);
    13831446        if (rc != EOK) {
    1384                 free(data);
     1447                free(_data);
    13851448                return rc;
    13861449        }
    13871450       
    1388         *blob = data;
     1451        if (nullterm)
     1452                ((char *) _data)[size] = 0;
     1453       
     1454        *data = _data;
    13891455        if (received != NULL)
    13901456                *received = size;
     
    13931459}
    13941460
    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)
     1461/** Wrapper for voiding any data that is about to be received
     1462 *
     1463 * This wrapper can be used to void any pending data
     1464 *
     1465 * @param retval Error value from @ref errno.h to be returned to the caller.
     1466 *
     1467 */
     1468void async_data_write_void(const int retval)
    14101469{
    14111470        ipc_callid_t callid;
    1412         size_t size;
    1413         if (!async_data_write_receive(&callid, &size)) {
     1471        async_data_write_receive(&callid, NULL);
     1472        ipc_answer_0(callid, retval);
     1473}
     1474
     1475/** Wrapper for forwarding any data that is about to be received
     1476 *
     1477 *
     1478 */
     1479int async_data_write_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     1480    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
     1481{
     1482        ipc_callid_t callid;
     1483        if (!async_data_write_receive(&callid, NULL)) {
    14141484                ipc_answer_0(callid, EINVAL);
    14151485                return EINVAL;
    14161486        }
    14171487       
    1418         if ((max_size > 0) && (size > max_size)) {
     1488        aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4,
     1489            dataptr);
     1490        if (msg == 0) {
    14191491                ipc_answer_0(callid, EINVAL);
    14201492                return EINVAL;
    14211493        }
    14221494       
    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;
     1495        int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,
     1496            IPC_FF_ROUTE_FROM_ME);
     1497        if (retval != EOK) {
     1498                async_wait_for(msg, NULL);
     1499                ipc_answer_0(callid, retval);
     1500                return retval;
     1501        }
     1502       
     1503        ipcarg_t rc;
     1504        async_wait_for(msg, &rc);
     1505       
     1506        return (int) rc;
    14381507}
    14391508
Note: See TracChangeset for help on using the changeset viewer.