Changeset 936351c1 in mainline for libipc/generic/ipc.c
- Timestamp:
- 2006-03-14T23:48:33Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d73942c
- Parents:
- 4f34b6a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libipc/generic/ipc.c
r4f34b6a r936351c1 29 29 #include <ipc.h> 30 30 #include <libc.h> 31 32 int ipc_call_sync(int phoneid, sysarg_t method, sysarg_t arg1, 33 sysarg_t *result) 31 #include <malloc.h> 32 #include <errno.h> 33 #include <list.h> 34 #include <stdio.h> 35 #include <unistd.h> 36 37 /** Structure used for keeping track of sent async msgs 38 * and queing unsent msgs 39 * 40 */ 41 typedef struct { 42 link_t list; 43 44 ipc_async_callback_t callback; 45 void *private; 46 union { 47 ipc_callid_t callid; 48 struct { 49 int phoneid; 50 ipc_data_t data; 51 } msg; 52 }u; 53 } async_call_t; 54 55 LIST_INITIALIZE(dispatched_calls); 56 LIST_INITIALIZE(queued_calls); 57 58 int ipc_call_sync(int phoneid, ipcarg_t method, ipcarg_t arg1, 59 ipcarg_t *result) 34 60 { 35 61 ipc_data_t resdata; 36 62 int callres; 37 63 38 callres = __SYSCALL4(SYS_IPC_CALL_SYNC , phoneid, method, arg1,64 callres = __SYSCALL4(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1, 39 65 (sysarg_t)&resdata); 40 66 if (callres) … … 45 71 } 46 72 47 int ipc_call_sync_3(int phoneid, sysarg_t method, sysarg_t arg1,48 sysarg_t arg2, sysarg_t arg3,49 sysarg_t *result1, sysarg_t *result2, sysarg_t *result3)73 int ipc_call_sync_3(int phoneid, ipcarg_t method, ipcarg_t arg1, 74 ipcarg_t arg2, ipcarg_t arg3, 75 ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3) 50 76 { 51 77 ipc_data_t data; … … 57 83 IPC_SET_ARG3(data, arg3); 58 84 59 callres = __SYSCALL2(SYS_IPC_CALL_SYNC _MEDIUM, phoneid, (sysarg_t)&data);85 callres = __SYSCALL2(SYS_IPC_CALL_SYNC, phoneid, (sysarg_t)&data); 60 86 if (callres) 61 87 return callres; … … 70 96 } 71 97 98 /** Syscall to send asynchronous message */ 99 static ipc_callid_t _ipc_call_async(int phoneid, ipc_data_t *data) 100 { 101 return __SYSCALL2(SYS_IPC_CALL_ASYNC, phoneid, (sysarg_t)data); 102 } 103 72 104 /** Send asynchronous message 73 105 * … … 75 107 * - if message cannot be temporarily sent, add to queue 76 108 */ 77 void ipc_call_async_2(int phoneid, sysarg_t method, sysarg_t arg1,78 sysarg_t arg2,109 void ipc_call_async_2(int phoneid, ipcarg_t method, ipcarg_t arg1, 110 ipcarg_t arg2, void *private, 79 111 ipc_async_callback_t callback) 80 112 { 113 async_call_t *call; 81 114 ipc_callid_t callid; 82 ipc_data_t data; /* Data storage for saving calls */ 83 84 callid = __SYSCALL4(SYS_IPC_CALL_ASYNC, phoneid, method, arg1, arg2); 115 116 call = malloc(sizeof(*call)); 117 if (!call) { 118 callback(private, ENOMEM, NULL); 119 } 120 121 callid = __SYSCALL4(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1, arg2); 85 122 if (callid == IPC_CALLRET_FATAL) { 86 123 /* Call asynchronous handler with error code */ 87 IPC_SET_RETVAL(data, IPC_CALLRET_FATAL); 88 callback(&data); 124 IPC_SET_RETVAL(call->u.msg.data, ENOENT); 125 callback(private, ENOENT, NULL); 126 free(call); 89 127 return; 90 128 } 129 130 call->callback = callback; 131 call->private = private; 132 91 133 if (callid == IPC_CALLRET_TEMPORARY) { 92 134 /* Add asynchronous call to queue of non-dispatched async calls */ 93 IPC_SET_METHOD(data, method); 94 IPC_SET_ARG1(data, arg1); 95 IPC_SET_ARG2(data, arg2); 96 135 call->u.msg.phoneid = phoneid; 136 IPC_SET_METHOD(call->u.msg.data, method); 137 IPC_SET_ARG1(call->u.msg.data, arg1); 138 IPC_SET_ARG2(call->u.msg.data, arg2); 139 140 list_append(&call->list, &queued_calls); 97 141 return; 98 142 } 99 /* Add callid to list of dispatched calls */ 100 143 call->u.callid = callid; 144 /* Add call to list of dispatched calls */ 145 list_append(&call->list, &dispatched_calls); 101 146 } 102 147 103 148 104 149 /** Send answer to a received call */ 105 void ipc_answer(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,106 sysarg_t arg2)150 void ipc_answer(ipc_callid_t callid, ipcarg_t retval, ipcarg_t arg1, 151 ipcarg_t arg2) 107 152 { 108 153 __SYSCALL4(SYS_IPC_ANSWER, callid, retval, arg1, arg2); … … 116 161 } 117 162 163 /** Try to dispatch queed calls from async queue */ 164 static void try_dispatch_queued_calls(void) 165 { 166 async_call_t *call; 167 ipc_callid_t callid; 168 169 while (!list_empty(&queued_calls)) { 170 call = list_get_instance(queued_calls.next, async_call_t, 171 list); 172 173 callid = _ipc_call_async(call->u.msg.phoneid, 174 &call->u.msg.data); 175 if (callid == IPC_CALLRET_TEMPORARY) 176 break; 177 list_remove(&call->list); 178 if (callid == IPC_CALLRET_FATAL) { 179 call->callback(call->private, ENOENT, NULL); 180 free(call); 181 } else { 182 call->u.callid = callid; 183 list_append(&call->list, &dispatched_calls); 184 } 185 } 186 } 187 188 /** Handle received answer 189 * 190 * TODO: Make it use hash table 191 * 192 * @param callid Callid (with first bit set) of the answered call 193 */ 194 static void handle_answer(ipc_callid_t callid, ipc_data_t *data) 195 { 196 link_t *item; 197 async_call_t *call; 198 199 callid &= ~IPC_CALLID_ANSWERED; 200 201 for (item = dispatched_calls.next; item != &dispatched_calls; 202 item = item->next) { 203 call = list_get_instance(item, async_call_t, list); 204 if (call->u.callid == callid) { 205 list_remove(&call->list); 206 call->callback(call->private, 207 IPC_GET_RETVAL(*data), 208 data); 209 return; 210 } 211 } 212 printf("Received unidentified answer: %P!!!\n", callid); 213 } 214 215 118 216 /** Wait for IPC call and return 119 217 * 120 218 * - dispatch ASYNC reoutines in the background 219 * @param data Space where the message is stored 220 * @return Callid or 0 if nothing available and started with 221 * IPC_WAIT_NONBLOCKING 121 222 */ 122 223 int ipc_wait_for_call(ipc_data_t *data, int flags) … … 125 226 126 227 do { 127 /* Try to dispatch non-dispatched async calls */ 228 try_dispatch_queued_calls(); 229 128 230 callid = _ipc_wait_for_call(data, flags); 129 if (callid & IPC_CALLID_ANSWERED) {130 /* TODO: Call async answer handler */131 }231 /* Handle received answers */ 232 if (callid & IPC_CALLID_ANSWERED) 233 handle_answer(callid, data); 132 234 } while (callid & IPC_CALLID_ANSWERED); 235 133 236 return callid; 134 237 }
Note:
See TracChangeset
for help on using the changeset viewer.