Changeset 2c0e5d2 in mainline
- Timestamp:
- 2009-05-19T21:47:00Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 27fd651
- Parents:
- 0c2eee0
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/ipc.h
r0c2eee0 r2c0e5d2 112 112 * These methods have special behaviour 113 113 */ 114 /** Clone connection. 115 * 116 * The calling task clones one of its phones for the callee. 117 * 118 * - ARG1 - The caller sets ARG1 to the phone of the cloned connection. 119 * - The callee gets the new phone from ARG1. 120 * - on answer, the callee acknowledges the new connection by sending EOK back 121 * or the kernel closes it 122 */ 123 #define IPC_M_CONNECTION_CLONE 1 124 /** Protocol for CONNECT - ME 125 * 126 * Through this call, the recipient learns about the new cloned connection. 127 * 128 * - ARG5 - the kernel sets ARG5 to contain the hash of the used phone 129 * - on asnwer, the callee acknowledges the new connection by sending EOK back 130 * or the kernel closes it 131 */ 132 #define IPC_M_CONNECT_ME 2 114 133 /** Protocol for CONNECT - TO - ME 115 134 * … … 128 147 * (on the receiving side) as ARG5 of the call. 129 148 */ 130 #define IPC_M_CONNECT_TO_ME 1149 #define IPC_M_CONNECT_TO_ME 3 131 150 /** Protocol for CONNECT - ME - TO 132 151 * … … 146 165 * 147 166 */ 148 #define IPC_M_CONNECT_ME_TO 2167 #define IPC_M_CONNECT_ME_TO 4 149 168 /** This message is sent to answerbox when the phone 150 169 * is hung up 151 170 */ 152 #define IPC_M_PHONE_HUNGUP 3171 #define IPC_M_PHONE_HUNGUP 5 153 172 154 173 /** Send as_area over IPC. … … 160 179 * - ARG1 - dst as_area base adress 161 180 */ 162 #define IPC_M_SHARE_OUT 4181 #define IPC_M_SHARE_OUT 6 163 182 164 183 /** Receive as_area over IPC. … … 172 191 * - ARG2 - flags that will be used for sharing 173 192 */ 174 #define IPC_M_SHARE_IN 5193 #define IPC_M_SHARE_IN 7 175 194 176 195 /** Send data to another address space over IPC. … … 183 202 * - ARG2 - final size of data to be copied 184 203 */ 185 #define IPC_M_DATA_WRITE 6204 #define IPC_M_DATA_WRITE 8 186 205 187 206 /** Receive data from another address space over IPC. … … 194 213 * - ARG2 - final size of data to be copied 195 214 */ 196 #define IPC_M_DATA_READ 7215 #define IPC_M_DATA_READ 9 197 216 198 217 /** Debug the recipient. … … 200 219 * - other arguments are specific to the debug method 201 220 */ 202 #define IPC_M_DEBUG_ALL 8221 #define IPC_M_DEBUG_ALL 10 203 222 204 223 /* Well-known methods */ -
kernel/generic/include/ipc/ipcrsc.h
r0c2eee0 r2c0e5d2 36 36 #define KERN_IPCRSC_H_ 37 37 38 #include <proc/task.h> 39 #include <ipc/ipc.h> 40 38 41 extern call_t * get_call(unative_t callid); 39 extern int phone_alloc( void);42 extern int phone_alloc(task_t *t); 40 43 extern void phone_connect(int phoneid, answerbox_t *box); 41 44 extern void phone_dealloc(int phoneid); -
kernel/generic/src/ipc/ipcrsc.c
r0c2eee0 r2c0e5d2 161 161 } 162 162 163 /** Allocate new phone slot in the current TASK structure. 163 /** Allocate new phone slot in the specified task. 164 * 165 * @param t Task for which to allocate a new phone. 164 166 * 165 167 * @return New phone handle or -1 if the phone handle limit is 166 168 * exceeded. 167 169 */ 168 int phone_alloc( void)170 int phone_alloc(task_t *t) 169 171 { 170 172 int i; 171 173 172 spinlock_lock(& TASK->lock);174 spinlock_lock(&t->lock); 173 175 for (i = 0; i < IPC_MAX_PHONES; i++) { 174 if ( TASK->phones[i].state == IPC_PHONE_HUNGUP &&175 atomic_get(& TASK->phones[i].active_calls) == 0)176 TASK->phones[i].state = IPC_PHONE_FREE;177 178 if ( TASK->phones[i].state == IPC_PHONE_FREE) {179 TASK->phones[i].state = IPC_PHONE_CONNECTING;176 if (t->phones[i].state == IPC_PHONE_HUNGUP && 177 atomic_get(&t->phones[i].active_calls) == 0) 178 t->phones[i].state = IPC_PHONE_FREE; 179 180 if (t->phones[i].state == IPC_PHONE_FREE) { 181 t->phones[i].state = IPC_PHONE_CONNECTING; 180 182 break; 181 183 } 182 184 } 183 spinlock_unlock(& TASK->lock);185 spinlock_unlock(&t->lock); 184 186 185 187 if (i == IPC_MAX_PHONES) -
kernel/generic/src/ipc/kbox.c
r0c2eee0 r2c0e5d2 249 249 } 250 250 251 newphid = phone_alloc( );251 newphid = phone_alloc(TASK); 252 252 if (newphid < 0) { 253 253 mutex_unlock(&ta->kb.cleanup_lock); -
kernel/generic/src/ipc/sysipc.c
r0c2eee0 r2c0e5d2 94 94 { 95 95 switch (method) { 96 case IPC_M_CONNECTION_CLONE: 97 case IPC_M_CONNECT_ME: 96 98 case IPC_M_PHONE_HUNGUP: 97 99 /* This message is meant only for the original recipient. */ … … 141 143 { 142 144 switch (IPC_GET_METHOD(call->data)) { 145 case IPC_M_CONNECTION_CLONE: 146 case IPC_M_CONNECT_ME: 143 147 case IPC_M_CONNECT_TO_ME: 144 148 case IPC_M_CONNECT_ME_TO: … … 183 187 return 0; 184 188 185 if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { 189 if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTION_CLONE) { 190 phoneid = IPC_GET_ARG1(*olddata); 191 phone_t *phone = &TASK->phones[phoneid]; 192 if (IPC_GET_RETVAL(answer->data) != EOK) { 193 /* 194 * The recipient of the cloned phone rejected the offer. 195 * In this case, the connection was established at the 196 * request time and therefore we need to slam the phone. 197 * We don't merely hangup as that would result in 198 * sending IPC_M_HUNGUP to the third party on the 199 * other side of the cloned phone. 200 */ 201 mutex_lock(&phone->lock); 202 if (phone->state == IPC_PHONE_CONNECTED) { 203 spinlock_lock(&phone->callee->lock); 204 list_remove(&phone->link); 205 phone->state = IPC_PHONE_SLAMMED; 206 spinlock_unlock(&phone->callee->lock); 207 } 208 mutex_unlock(&phone->lock); 209 } 210 } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME) { 211 phone_t *phone = (phone_t *)IPC_GET_ARG5(*olddata); 212 if (IPC_GET_RETVAL(answer->data) != EOK) { 213 /* 214 * The other party on the cloned phoned rejected our 215 * request for connection on the protocol level. 216 * We need to break the connection without sending 217 * IPC_M_HUNGUP back. 218 */ 219 mutex_lock(&phone->lock); 220 if (phone->state == IPC_PHONE_CONNECTED) { 221 spinlock_lock(&phone->callee->lock); 222 list_remove(&phone->link); 223 phone->state = IPC_PHONE_SLAMMED; 224 spinlock_unlock(&phone->callee->lock); 225 } 226 mutex_unlock(&phone->lock); 227 } 228 } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) { 186 229 phoneid = IPC_GET_ARG5(*olddata); 187 if (IPC_GET_RETVAL(answer->data) ) {230 if (IPC_GET_RETVAL(answer->data) != EOK) { 188 231 /* The connection was not accepted */ 189 232 phone_dealloc(phoneid); … … 197 240 } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) { 198 241 /* If the users accepted call, connect */ 199 if ( !IPC_GET_RETVAL(answer->data)) {242 if (IPC_GET_RETVAL(answer->data) == EOK) { 200 243 ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata), 201 244 &TASK->answerbox); … … 309 352 310 353 switch (IPC_GET_METHOD(call->data)) { 354 case IPC_M_CONNECTION_CLONE: { 355 phone_t *cloned_phone; 356 GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data), 357 return ENOENT); 358 if (cloned_phone < phone) { 359 mutex_lock(&cloned_phone->lock); 360 mutex_lock(&phone->lock); 361 } else { 362 mutex_lock(&phone->lock); 363 mutex_lock(&cloned_phone->lock); 364 } 365 if ((cloned_phone->state != IPC_PHONE_CONNECTED) || 366 phone->state != IPC_PHONE_CONNECTED) { 367 mutex_unlock(&cloned_phone->lock); 368 mutex_unlock(&phone->lock); 369 return EINVAL; 370 } 371 /* 372 * We can be pretty sure now that both tasks exist and we are 373 * connected to them. As we continue to hold the phone locks, 374 * we are effectively preventing them from finishing their 375 * potential cleanup. 376 */ 377 newphid = phone_alloc(phone->callee->task); 378 if (newphid < 0) { 379 mutex_unlock(&cloned_phone->lock); 380 mutex_unlock(&phone->lock); 381 return ELIMIT; 382 } 383 ipc_phone_connect(&phone->callee->task->phones[newphid], 384 cloned_phone->callee); 385 mutex_unlock(&cloned_phone->lock); 386 mutex_unlock(&phone->lock); 387 /* Set the new phone for the callee. */ 388 IPC_SET_ARG1(call->data, newphid); 389 break; 390 } 391 case IPC_M_CONNECT_ME: 392 IPC_SET_ARG5(call->data, (unative_t) phone); 393 break; 311 394 case IPC_M_CONNECT_ME_TO: 312 newphid = phone_alloc( );395 newphid = phone_alloc(TASK); 313 396 if (newphid < 0) 314 397 return ELIMIT; … … 400 483 401 484 if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) { 402 phoneid = phone_alloc( );485 phoneid = phone_alloc(TASK); 403 486 if (phoneid < 0) { /* Failed to allocate phone */ 404 487 IPC_SET_RETVAL(call->data, ELIMIT); -
uspace/lib/libc/generic/async.c
r0c2eee0 r2c0e5d2 593 593 594 594 switch (IPC_GET_METHOD(*call)) { 595 case IPC_M_CONNECT_ME: 595 596 case IPC_M_CONNECT_ME_TO: 596 597 /* Open new connection with fibril etc. */
Note:
See TracChangeset
for help on using the changeset viewer.