Changeset 2c0e5d2 in mainline


Ignore:
Timestamp:
2009-05-19T21:47:00Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
27fd651
Parents:
0c2eee0
Message:

Add IPC_M_CONNECTION_CLONE and IPC_M_CONNECT_ME.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ipc/ipc.h

    r0c2eee0 r2c0e5d2  
    112112 * These methods have special behaviour
    113113 */
     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
    114133/** Protocol for CONNECT - TO - ME
    115134 *
     
    128147 *                       (on the receiving side) as ARG5 of the call.
    129148 */
    130 #define IPC_M_CONNECT_TO_ME     1
     149#define IPC_M_CONNECT_TO_ME     3       
    131150/** Protocol for CONNECT - ME - TO
    132151 *
     
    146165 *
    147166 */
    148 #define IPC_M_CONNECT_ME_TO     2
     167#define IPC_M_CONNECT_ME_TO     4       
    149168/** This message is sent to answerbox when the phone
    150169 * is hung up
    151170 */
    152 #define IPC_M_PHONE_HUNGUP      3
     171#define IPC_M_PHONE_HUNGUP      5
    153172
    154173/** Send as_area over IPC.
     
    160179 * - ARG1 - dst as_area base adress
    161180 */
    162 #define IPC_M_SHARE_OUT         4       
     181#define IPC_M_SHARE_OUT         6       
    163182
    164183/** Receive as_area over IPC.
     
    172191 * - ARG2 - flags that will be used for sharing
    173192 */
    174 #define IPC_M_SHARE_IN          5       
     193#define IPC_M_SHARE_IN          7       
    175194
    176195/** Send data to another address space over IPC.
     
    183202 * - ARG2 - final size of data to be copied
    184203 */
    185 #define IPC_M_DATA_WRITE        6
     204#define IPC_M_DATA_WRITE        8
    186205
    187206/** Receive data from another address space over IPC.
     
    194213 * - ARG2 - final size of data to be copied
    195214 */
    196 #define IPC_M_DATA_READ         7
     215#define IPC_M_DATA_READ         9
    197216
    198217/** Debug the recipient.
     
    200219 * - other arguments are specific to the debug method
    201220 */
    202 #define IPC_M_DEBUG_ALL         8
     221#define IPC_M_DEBUG_ALL         10
    203222
    204223/* Well-known methods */
  • kernel/generic/include/ipc/ipcrsc.h

    r0c2eee0 r2c0e5d2  
    3636#define KERN_IPCRSC_H_
    3737
     38#include <proc/task.h>
     39#include <ipc/ipc.h>
     40
    3841extern call_t * get_call(unative_t callid);
    39 extern int phone_alloc(void);
     42extern int phone_alloc(task_t *t);
    4043extern void phone_connect(int phoneid, answerbox_t *box);
    4144extern void phone_dealloc(int phoneid);
  • kernel/generic/src/ipc/ipcrsc.c

    r0c2eee0 r2c0e5d2  
    161161}
    162162
    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.
    164166 *
    165167 * @return              New phone handle or -1 if the phone handle limit is
    166168 *                      exceeded.
    167169 */
    168 int phone_alloc(void)
     170int phone_alloc(task_t *t)
    169171{
    170172        int i;
    171173
    172         spinlock_lock(&TASK->lock);
     174        spinlock_lock(&t->lock);
    173175        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;
    180182                        break;
    181183                }
    182184        }
    183         spinlock_unlock(&TASK->lock);
     185        spinlock_unlock(&t->lock);
    184186
    185187        if (i == IPC_MAX_PHONES)
  • kernel/generic/src/ipc/kbox.c

    r0c2eee0 r2c0e5d2  
    249249        }
    250250
    251         newphid = phone_alloc();
     251        newphid = phone_alloc(TASK);
    252252        if (newphid < 0) {
    253253                mutex_unlock(&ta->kb.cleanup_lock);
  • kernel/generic/src/ipc/sysipc.c

    r0c2eee0 r2c0e5d2  
    9494{
    9595        switch (method) {
     96        case IPC_M_CONNECTION_CLONE:
     97        case IPC_M_CONNECT_ME:
    9698        case IPC_M_PHONE_HUNGUP:
    9799                /* This message is meant only for the original recipient. */
     
    141143{
    142144        switch (IPC_GET_METHOD(call->data)) {
     145        case IPC_M_CONNECTION_CLONE:
     146        case IPC_M_CONNECT_ME:
    143147        case IPC_M_CONNECT_TO_ME:
    144148        case IPC_M_CONNECT_ME_TO:
     
    183187                return 0;
    184188
    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) {
    186229                phoneid = IPC_GET_ARG5(*olddata);
    187                 if (IPC_GET_RETVAL(answer->data)) {
     230                if (IPC_GET_RETVAL(answer->data) != EOK) {
    188231                        /* The connection was not accepted */
    189232                        phone_dealloc(phoneid);
     
    197240        } else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
    198241                /* If the users accepted call, connect */
    199                 if (!IPC_GET_RETVAL(answer->data)) {
     242                if (IPC_GET_RETVAL(answer->data) == EOK) {
    200243                        ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata),
    201244                            &TASK->answerbox);
     
    309352
    310353        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;
    311394        case IPC_M_CONNECT_ME_TO:
    312                 newphid = phone_alloc();
     395                newphid = phone_alloc(TASK);
    313396                if (newphid < 0)
    314397                        return ELIMIT;
     
    400483
    401484        if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) {
    402                 phoneid = phone_alloc();
     485                phoneid = phone_alloc(TASK);
    403486                if (phoneid < 0) { /* Failed to allocate phone */
    404487                        IPC_SET_RETVAL(call->data, ELIMIT);
  • uspace/lib/libc/generic/async.c

    r0c2eee0 r2c0e5d2  
    593593       
    594594        switch (IPC_GET_METHOD(*call)) {
     595        case IPC_M_CONNECT_ME:
    595596        case IPC_M_CONNECT_ME_TO:
    596597                /* Open new connection with fibril etc. */
Note: See TracChangeset for help on using the changeset viewer.