Changeset 9f22213 in mainline for generic/src/ipc/ipc.c


Ignore:
Timestamp:
2006-03-19T12:43:12Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7c7aae16
Parents:
b4b45210
Message:

More IPC stuff, added correct closing of connections from both sides.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/ipc/ipc.c

    rb4b45210 r9f22213  
    105105
    106106        ASSERT(!phone->callee);
    107         phone->busy = 1;
     107        phone->busy = IPC_BUSY_CONNECTED;
    108108        phone->callee = box;
    109109
     
    121121        spinlock_initialize(&phone->lock, "phone_lock");
    122122        phone->callee = NULL;
    123         phone->busy = 0;
     123        phone->busy = IPC_BUSY_FREE;
     124        atomic_set(&phone->active_calls, 0);
    124125}
    125126
     
    172173static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
    173174{
    174         atomic_inc(&phone->active_calls);
    175         call->data.phone = phone;
     175        if (! (call->flags & IPC_CALL_FORWARDED)) {
     176                atomic_inc(&phone->active_calls);
     177                call->data.phone = phone;
     178        }
    176179
    177180        spinlock_lock(&box->lock);
     
    186189 * @param request Request to be sent
    187190 */
    188 void ipc_call(phone_t *phone, call_t *call)
     191int ipc_call(phone_t *phone, call_t *call)
    189192{
    190193        answerbox_t *box;
     
    196199                /* Trying to send over disconnected phone */
    197200                spinlock_unlock(&phone->lock);
    198 
    199                 call->data.phone = phone;
    200                 IPC_SET_RETVAL(call->data, ENOENT);
     201                if (call->flags & IPC_CALL_FORWARDED) {
     202                        IPC_SET_RETVAL(call->data, EFORWARD);
     203                } else { /* Simulate sending a message */
     204                        call->data.phone = phone;
     205                        atomic_inc(&phone->active_calls);
     206                        if (phone->busy == IPC_BUSY_CONNECTED)
     207                                IPC_SET_RETVAL(call->data, EHANGUP);
     208                        else
     209                                IPC_SET_RETVAL(call->data, ENOENT);
     210                }
     211
    201212                _ipc_answer_free_call(call);
    202                 return;
     213                return ENOENT;
    203214        }
    204215        _ipc_call(phone, box, call);
    205216       
    206217        spinlock_unlock(&phone->lock);
     218        return 0;
    207219}
    208220
     
    221233        box = phone->callee;
    222234        if (!box) {
     235                if (phone->busy == IPC_BUSY_CONNECTING) {
     236                        spinlock_unlock(&phone->lock);
     237                        return -1;
     238                }
     239                /* Already disconnected phone */
     240                phone->busy = IPC_BUSY_FREE;
    223241                spinlock_unlock(&phone->lock);
    224                 return -1;
     242                return 0;
    225243        }
    226244
     
    235253        _ipc_call(phone, box, call);
    236254
    237         phone->busy = 0;
     255        phone->busy = IPC_BUSY_FREE;
    238256
    239257        spinlock_unlock(&phone->lock);
     
    247265 * @param newbox Target answerbox
    248266 * @param oldbox Old answerbox
    249  */
    250 void ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox)
     267 * @return 0 on forward ok, error code, if there was error
     268 *
     269 * - the return value serves only as an information for the forwarder,
     270 *   the original caller is notified automatically with EFORWARD
     271 */
     272int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox)
    251273{
    252274        spinlock_lock(&oldbox->lock);
    253         atomic_dec(&call->data.phone->active_calls);
    254275        list_remove(&call->list);
    255276        spinlock_unlock(&oldbox->lock);
    256277
    257         ipc_call(newphone, call);
     278        return ipc_call(newphone, call);
    258279}
    259280
     
    280301                request = list_get_instance(box->answers.next, call_t, list);
    281302                list_remove(&request->list);
    282                 printf("%d %P\n", IPC_GET_METHOD(request->data),
    283                        request->data.phone);
    284303                atomic_dec(&request->data.phone->active_calls);
    285304        } else if (!list_empty(&box->calls)) {
     
    314333void ipc_cleanup(task_t *task)
    315334{
    316         /* Cancel all calls in my dispatch queue */
     335        int i;
     336
     337        /* Disconnect all our phones ('ipc_phone_hangup') */
     338        for (i=0;i < IPC_MAX_PHONES; i++)
     339                ipc_phone_hangup(&task->phones[i]);
     340
     341        /* Disconnect all phones connected to answerbox */
     342
     343        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
    317344       
    318 }
     345        /* Wait for all async answers to arrive */
     346}
Note: See TracChangeset for help on using the changeset viewer.