Changeset b4cbef1 in mainline
- Timestamp:
- 2010-02-03T16:52:37Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3b3e776, eda925a
- Parents:
- 472c09d
- Location:
- uspace
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/async.c
r472c09d rb4cbef1 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 binary data via the async_data_write_*1385 /** Wrapper for receiving binary data 1348 1386 * 1349 1387 * This wrapper only makes it more comfortable to use async_data_write_* 1350 * functions to receive b lobs.1388 * functions to receive binary data. 1351 1389 * 1352 1390 * @param data Pointer to data pointer (which should be later disposed 1353 1391 * by free()). If the operation fails, the pointer is not 1354 1392 * touched. 1393 * @param min_size Minimum size (in bytes) of the data to receive. 1355 1394 * @param max_size Maximum size (in bytes) of the data to receive. 0 means 1356 1395 * no limit. … … 1362 1401 * 1363 1402 */ 1364 int async_data_receive(void **data, const size_t m ax_size,1365 const size_t granularity, size_t *received)1403 int async_data_receive(void **data, const size_t min_size, 1404 const size_t max_size, const size_t granularity, size_t *received) 1366 1405 { 1367 1406 ipc_callid_t callid; … … 1372 1411 } 1373 1412 1413 if (size < min_size) { 1414 ipc_answer_0(callid, EINVAL); 1415 return EINVAL; 1416 } 1417 1374 1418 if ((max_size > 0) && (size > max_size)) { 1375 1419 ipc_answer_0(callid, EINVAL); … … 1401 1445 } 1402 1446 1403 /** Wrapper for receiving strings via the async_data_write_*1447 /** Wrapper for receiving strings 1404 1448 * 1405 1449 * This wrapper only makes it more comfortable to use async_data_write_* … … 1450 1494 } 1451 1495 1496 /** Wrapper for voiding any data that is about to be received 1497 * 1498 * This wrapper can be used to void any pending data 1499 * 1500 * @param retval Error value from @ref errno.h to be returned to the caller. 1501 * 1502 */ 1503 void async_data_void(const int retval) 1504 { 1505 ipc_callid_t callid; 1506 async_data_write_receive(&callid, NULL); 1507 ipc_answer_0(callid, retval); 1508 } 1509 1510 /** Wrapper for forwarding any data that is about to be received 1511 * 1512 * 1513 */ 1514 int async_data_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, 1515 ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) 1516 { 1517 ipc_callid_t callid; 1518 if (!async_data_write_receive(&callid, NULL)) { 1519 ipc_answer_0(callid, EINVAL); 1520 return EINVAL; 1521 } 1522 1523 aid_t msg = async_send_fast(phoneid, method, arg1, arg2, arg3, arg4, 1524 dataptr); 1525 if (msg == 0) { 1526 ipc_answer_0(callid, EINVAL); 1527 return EINVAL; 1528 } 1529 1530 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0, 1531 IPC_FF_ROUTE_FROM_ME); 1532 if (retval != EOK) { 1533 ipc_answer_0(callid, retval); 1534 return retval; 1535 } 1536 1537 ipcarg_t rc; 1538 async_wait_for(msg, &rc); 1539 1540 return (int) rc; 1541 } 1542 1452 1543 /** @} 1453 1544 */ -
uspace/lib/libc/include/async.h
r472c09d rb4cbef1 277 277 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *); 278 278 extern int async_share_out_finalize(ipc_callid_t, void *); 279 280 /* 281 * User-friendly wrappers for async_data_read_forward_fast(). 282 */ 283 #define async_data_read_forward_0_0(phoneid, method, answer) \ 284 async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL) 285 #define async_data_read_forward_0_1(phoneid, method, answer) \ 286 async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer)) 287 #define async_data_read_forward_1_0(phoneid, method, arg1, answer) \ 288 async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL) 289 #define async_data_read_forward_1_1(phoneid, method, arg1, answer) \ 290 async_data_read_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer)) 291 #define async_data_read_forward_2_0(phoneid, method, arg1, arg2, answer) \ 292 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL) 293 #define async_data_read_forward_2_1(phoneid, method, arg1, arg2, answer) \ 294 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \ 295 (answer)) 296 #define async_data_read_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \ 297 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 298 NULL) 299 #define async_data_read_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \ 300 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 301 (answer)) 302 #define async_data_read_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 303 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 304 (arg4), NULL) 305 #define async_data_read_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 306 async_data_read_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 307 (arg4), (answer)) 308 279 309 extern int async_data_read_start(int, void *, size_t); 280 310 extern int async_data_read_receive(ipc_callid_t *, size_t *); 281 311 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t); 312 extern int async_data_read_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, 313 ipcarg_t, ipcarg_t, ipc_call_t *); 314 315 /* 316 * User-friendly wrappers for async_data_forward_fast(). 317 */ 318 #define async_data_forward_0_0(phoneid, method, answer) \ 319 async_data_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL) 320 #define async_data_forward_0_1(phoneid, method, answer) \ 321 async_data_forward_fast((phoneid), (method), 0, 0, 0, 0, (answer)) 322 #define async_data_forward_1_0(phoneid, method, arg1, answer) \ 323 async_data_forward_fast((phoneid), (method), (arg1), 0, 0, 0, NULL) 324 #define async_data_forward_1_1(phoneid, method, arg1, answer) \ 325 async_data_forward_fast((phoneid), (method), (arg1), 0, 0, 0, (answer)) 326 #define async_data_forward_2_0(phoneid, method, arg1, arg2, answer) \ 327 async_data_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL) 328 #define async_data_forward_2_1(phoneid, method, arg1, arg2, answer) \ 329 async_data_forward_fast((phoneid), (method), (arg1), (arg2), 0, 0, \ 330 (answer)) 331 #define async_data_forward_3_0(phoneid, method, arg1, arg2, arg3, answer) \ 332 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 333 NULL) 334 #define async_data_forward_3_1(phoneid, method, arg1, arg2, arg3, answer) \ 335 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 336 (answer)) 337 #define async_data_forward_4_0(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 338 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 339 (arg4), NULL) 340 #define async_data_forward_4_1(phoneid, method, arg1, arg2, arg3, arg4, answer) \ 341 async_data_forward_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 342 (arg4), (answer)) 343 282 344 extern int async_data_write_start(int, const void *, size_t); 283 345 extern int async_data_write_receive(ipc_callid_t *, size_t *); 284 346 extern int async_data_write_finalize(ipc_callid_t, void *, size_t); 285 286 extern int async_data_receive(void **, const size_t,const size_t, size_t *);347 extern int async_data_receive(void **, const size_t, const size_t, 348 const size_t, size_t *); 287 349 extern int async_string_receive(char **, const size_t, size_t *); 350 extern void async_data_void(const int); 351 extern int async_data_forward_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, 352 ipcarg_t, ipc_call_t *); 288 353 289 354 #endif -
uspace/lib/libfs/libfs.c
r472c09d rb4cbef1 161 161 /* Accept the phone */ 162 162 callid = async_get_call(&call); 163 int mountee_phone = (int) IPC_GET_ARG1(call);163 int mountee_phone = (int) IPC_GET_ARG1(call); 164 164 if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) || 165 165 (mountee_phone < 0)) { … … 172 172 ipc_answer_0(callid, EOK); 173 173 174 res = async_data_write_receive(&callid, NULL);175 if (!res) {176 ipc_hangup(mountee_phone);177 ipc_answer_0(callid, EINVAL);178 ipc_answer_0(rid, EINVAL);179 return;180 }181 182 174 fs_node_t *fn; 183 175 res = ops->node_get(&fn, mp_dev_handle, mp_fs_index); 184 176 if ((res != EOK) || (!fn)) { 185 177 ipc_hangup(mountee_phone); 186 ipc_answer_0(callid,combine_rc(res, ENOENT));178 async_data_void(combine_rc(res, ENOENT)); 187 179 ipc_answer_0(rid, combine_rc(res, ENOENT)); 188 180 return; … … 192 184 ipc_hangup(mountee_phone); 193 185 (void) ops->node_put(fn); 194 ipc_answer_0(callid,EBUSY);186 async_data_void(EBUSY); 195 187 ipc_answer_0(rid, EBUSY); 196 188 return; … … 201 193 ipc_hangup(mountee_phone); 202 194 (void) ops->node_put(fn); 203 ipc_answer_0(callid,rc);195 async_data_void(rc); 204 196 ipc_answer_0(rid, rc); 205 197 return; … … 207 199 208 200 ipc_call_t answer; 209 aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,201 rc = async_data_forward_1_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle, 210 202 &answer); 211 ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);212 async_wait_for(msg, &rc);213 203 214 204 if (rc == EOK) { -
uspace/srv/clip/clip.c
r472c09d rb4cbef1 65 65 break; 66 66 case CLIPBOARD_TAG_DATA: 67 rc = async_data_receive(&data, 0, 0, &size);67 rc = async_data_receive(&data, 0, 0, 0, &size); 68 68 if (rc != EOK) { 69 69 ipc_answer_0(rid, rc); -
uspace/srv/hid/console/console.c
r472c09d rb4cbef1 477 477 void *buf; 478 478 size_t size; 479 int rc = async_data_receive(&buf, 0, 0, &size);479 int rc = async_data_receive(&buf, 0, 0, 0, &size); 480 480 481 481 if (rc != EOK) { -
uspace/srv/loader/main.c
r472c09d rb4cbef1 230 230 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 231 231 { 232 void*buf;232 fdi_node_t *buf; 233 233 size_t buf_size; 234 int rc = async_data_receive(&buf, 0, sizeof(fdi_node_t), &buf_size);234 int rc = async_data_receive(&buf, 0, 0, sizeof(fdi_node_t), &buf_size); 235 235 236 236 if (rc == EOK) { … … 252 252 int i; 253 253 for (i = 0; i < count; i++) 254 _filv[i] = & ((fdi_node_t *) buf)[i];254 _filv[i] = &buf[i]; 255 255 256 256 _filv[count] = NULL; … … 266 266 267 267 filc = count; 268 fil_buf = (fdi_node_t *)buf;268 fil_buf = buf; 269 269 filv = _filv; 270 270 } -
uspace/srv/vfs/vfs_ops.c
r472c09d rb4cbef1 794 794 795 795 /* 796 * Now we need to receive a call with client's797 * IPC_M_DATA_READ/IPC_M_DATA_WRITE request.798 */799 ipc_callid_t callid;800 int res;801 if (read)802 res = async_data_read_receive(&callid, NULL);803 else804 res = async_data_write_receive(&callid, NULL);805 if (!res) {806 ipc_answer_0(callid, EINVAL);807 ipc_answer_0(rid, EINVAL);808 return;809 }810 811 /*812 796 * Lock the open file structure so that no other thread can manipulate 813 797 * the same open file at a time. … … 833 817 } 834 818 835 int fs_phone = vfs_grab_phone(file->node->fs_handle); 836 837 /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */ 838 aid_t msg; 839 ipc_call_t answer; 840 if (!read && file->append) 841 file->pos = file->node->size; 842 msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE, 843 file->node->dev_handle, file->node->index, file->pos, &answer); 844 845 /* 846 * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the 819 int fs_phone = vfs_grab_phone(file->node->fs_handle); 820 821 /* 822 * Make a VFS_READ/VFS_WRITE request at the destination FS server 823 * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the 847 824 * destination FS server. The call will be routed as if sent by 848 825 * ourselves. Note that call arguments are immutable in this case so we 849 826 * don't have to bother. 850 827 */ 851 ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);852 853 /* Wait for reply from the FS server. */854 828 ipcarg_t rc; 855 async_wait_for(msg, &rc); 829 ipc_call_t answer; 830 if (read) { 831 if (file->append) 832 file->pos = file->node->size; 833 834 rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ, 835 file->node->dev_handle, file->node->index, file->pos, 836 &answer); 837 } else { 838 rc = async_data_forward_3_1(fs_phone, VFS_OUT_WRITE, 839 file->node->dev_handle, file->node->index, file->pos, 840 &answer); 841 } 856 842 857 843 vfs_release_phone(fs_phone); 858 844 859 845 size_t bytes = IPC_GET_ARG1(answer); 860 846 861 847 if (file->node->type == VFS_NODE_DIRECTORY) 862 848 fibril_rwlock_read_unlock(&namespace_rwlock); -
uspace/srv/vfs/vfs_register.c
r472c09d rb4cbef1 110 110 void vfs_register(ipc_callid_t rid, ipc_call_t *request) 111 111 { 112 ipc_callid_t callid;113 ipc_call_t call;114 int rc;115 size_t size;116 117 112 dprintf("Processing VFS_REGISTER request received from %p.\n", 118 113 request->in_phone_hash); 119 120 /* 121 * The first call has to be IPC_M_DATA_SEND in which we receive the 122 * VFS info structure from the client FS. 123 */ 124 if (!async_data_write_receive(&callid, &size)) { 125 /* 126 * The client doesn't obey the same protocol as we do. 127 */ 128 dprintf("Receiving of VFS info failed.\n"); 129 ipc_answer_0(callid, EINVAL); 130 ipc_answer_0(rid, EINVAL); 131 return; 132 } 133 134 dprintf("VFS info received, size = %d\n", size); 135 136 /* 137 * We know the size of the VFS info structure. See if the client 138 * understands this easy concept too. 139 */ 140 if (size != sizeof(vfs_info_t)) { 141 /* 142 * The client is sending us something, which cannot be 143 * the info structure. 144 */ 145 dprintf("Received VFS info has bad size.\n"); 146 ipc_answer_0(callid, EINVAL); 147 ipc_answer_0(rid, EINVAL); 148 return; 149 } 150 151 /* 152 * Allocate and initialize a buffer for the fs_info structure. 153 */ 154 fs_info_t *fs_info; 155 fs_info = (fs_info_t *) malloc(sizeof(fs_info_t)); 156 if (!fs_info) { 157 dprintf("Could not allocate memory for FS info.\n"); 158 ipc_answer_0(callid, ENOMEM); 159 ipc_answer_0(rid, ENOMEM); 160 return; 161 } 162 link_initialize(&fs_info->fs_link); 163 fibril_mutex_initialize(&fs_info->phone_lock); 164 165 rc = async_data_write_finalize(callid, &fs_info->vfs_info, size); 114 115 vfs_info_t *vfs_info; 116 int rc = async_data_receive(&vfs_info, sizeof(vfs_info_t), 117 sizeof(vfs_info_t), 0, NULL); 118 166 119 if (rc != EOK) { 167 120 dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n", 168 121 rc); 169 free(fs_info);170 ipc_answer_0(callid, rc);171 122 ipc_answer_0(rid, rc); 172 123 return; 173 124 } 174 125 126 /* 127 * Allocate and initialize a buffer for the fs_info structure. 128 */ 129 fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t)); 130 if (!fs_info) { 131 dprintf("Could not allocate memory for FS info.\n"); 132 ipc_answer_0(rid, ENOMEM); 133 return; 134 } 135 136 link_initialize(&fs_info->fs_link); 137 fibril_mutex_initialize(&fs_info->phone_lock); 138 fs_info->vfs_info = *vfs_info; 139 free(vfs_info); 140 175 141 dprintf("VFS info delivered.\n"); 176 142 177 143 if (!vfs_info_sane(&fs_info->vfs_info)) { 178 144 free(fs_info); 179 ipc_answer_0(callid, EINVAL);180 145 ipc_answer_0(rid, EINVAL); 181 146 return; 182 147 } 183 148 184 149 fibril_mutex_lock(&fs_head_lock); 185 150 186 151 /* 187 152 * Check for duplicit registrations. … … 194 159 fibril_mutex_unlock(&fs_head_lock); 195 160 free(fs_info); 196 ipc_answer_0(callid, EEXISTS);197 161 ipc_answer_0(rid, EEXISTS); 198 162 return; 199 163 } 200 164 201 165 /* 202 166 * Add fs_info to the list of registered FS's. … … 210 174 * which to forward VFS requests to it. 211 175 */ 212 callid = async_get_call(&call); 176 ipc_call_t call; 177 ipc_callid_t callid = async_get_call(&call); 213 178 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { 214 179 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); … … 222 187 fs_info->phone = IPC_GET_ARG5(call); 223 188 ipc_answer_0(callid, EOK); 224 189 225 190 dprintf("Callback connection to FS created.\n"); 226 191 227 192 /* 228 193 * The client will want us to send him the address space area with PLB. 229 194 */ 230 195 196 size_t size; 231 197 if (!async_share_in_receive(&callid, &size)) { 232 198 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); … … 253 219 return; 254 220 } 255 221 256 222 /* 257 223 * Commit to read-only sharing the PLB with the client. … … 259 225 (void) async_share_in_finalize(callid, plb, 260 226 AS_AREA_READ | AS_AREA_CACHEABLE); 261 227 262 228 dprintf("Sharing PLB.\n"); 263 229 264 230 /* 265 231 * That was it. The FS has been registered.
Note:
See TracChangeset
for help on using the changeset viewer.