Changeset 5d3ed34 in mainline


Ignore:
Timestamp:
2012-09-03T21:39:37Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9c9bbaf
Parents:
9ef1b79b
Message:

Make sure that both dispatched and non-dispatched calls are properly
answered in ipc_cleanup_call_list().

  • Define simple request_preprocess() hook for IPC_M_CONNECT_TO_ME to detect when the request_process() was not called and no resources allocated so that answer_cleanup() does not attempt to free non-existent resources.
Location:
kernel/generic
Files:
1 added
5 edited

Legend:

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

    r9ef1b79b r5d3ed34  
    179179extern void ipc_backsend_err(phone_t *, call_t *, sysarg_t);
    180180extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
    181 extern void ipc_cleanup_call_list(list_t *);
     181extern void ipc_cleanup_call_list(answerbox_t *, list_t *);
    182182
    183183extern void ipc_print_task(task_id_t);
  • kernel/generic/src/ipc/ipc.c

    r9ef1b79b r5d3ed34  
    4646#include <ipc/event.h>
    4747#include <ipc/sysipc_ops.h>
     48#include <ipc/sysipc_priv.h>
    4849#include <errno.h>
    4950#include <mm/slab.h>
     
    475476/** Answer all calls from list with EHANGUP answer.
    476477 *
     478 * @param box Answerbox with the list.
    477479 * @param lst Head of the list to be cleaned up.
    478  *
    479  */
    480 void ipc_cleanup_call_list(list_t *lst)
    481 {
     480 */
     481void ipc_cleanup_call_list(answerbox_t *box, list_t *lst)
     482{
     483        irq_spinlock_lock(&box->lock, true);
    482484        while (!list_empty(lst)) {
    483485                call_t *call = list_get_instance(list_first(lst), call_t,
     
    485487               
    486488                list_remove(&call->ab_link);
    487                
     489
     490                irq_spinlock_unlock(&box->lock, true);
     491
     492                ipc_data_t old = call->data;
    488493                IPC_SET_RETVAL(call->data, EHANGUP);
     494                answer_preprocess(call, &old);
    489495                _ipc_answer_free_call(call, true);
    490         }
     496
     497                irq_spinlock_lock(&box->lock, true);
     498        }
     499        irq_spinlock_unlock(&box->lock, true);
    491500}
    492501
     
    694703       
    695704        /* Answer all messages in 'calls' and 'dispatched_calls' queues */
    696         irq_spinlock_lock(&TASK->answerbox.lock, true);
    697         ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
    698         ipc_cleanup_call_list(&TASK->answerbox.calls);
    699         irq_spinlock_unlock(&TASK->answerbox.lock, true);
     705        ipc_cleanup_call_list(&TASK->answerbox,
     706            &TASK->answerbox.dispatched_calls);
     707        ipc_cleanup_call_list(&TASK->answerbox, &TASK->answerbox.calls);
    700708
    701709        ipc_forget_all_active_calls();
  • kernel/generic/src/ipc/kbox.c

    r9ef1b79b r5d3ed34  
    8888       
    8989        /* Answer all messages in 'calls' and 'dispatched_calls' queues. */
    90         irq_spinlock_lock(&TASK->kb.box.lock, true);
    91         ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls);
    92         ipc_cleanup_call_list(&TASK->kb.box.calls);
    93         irq_spinlock_unlock(&TASK->kb.box.lock, true);
     90        ipc_cleanup_call_list(&TASK->kb.box, &TASK->kb.box.dispatched_calls);
     91        ipc_cleanup_call_list(&TASK->kb.box, &TASK->kb.box.calls);
    9492}
    9593
  • kernel/generic/src/ipc/ops/concttome.c

    r9ef1b79b r5d3ed34  
    4040#include <arch.h>
    4141
     42static int request_preprocess(call_t *call, phone_t *phone)
     43{
     44        /* Start with the assumption that there is no allocated phoneid. */
     45        IPC_SET_ARG5(call->data, -1);
     46        return EOK;
     47}
     48
    4249static int request_process(call_t *call, answerbox_t *box)
    4350{
    4451        int phoneid = phone_alloc(TASK);
    4552
    46         if (phoneid < 0) {
    47                 IPC_SET_RETVAL(call->data, ELIMIT);
    48                 /*
    49                  * This is a shortcut which bypasses the standard call
    50                  * processing hooks. We are still playing it save here as
    51                  * there is no state to be cleaned up at this stage.
    52                  */
    53                 ipc_answer(box, call);
    54                 return -1;
    55         }
    56                
    5753        IPC_SET_ARG5(call->data, phoneid);
    5854       
     
    6460        int phoneid = (int) IPC_GET_ARG5(*olddata);
    6561
    66         phone_dealloc(phoneid);
     62        if (phoneid >= 0)
     63                phone_dealloc(phoneid);
    6764}
    6865
     
    7471                /* The connection was not accepted */
    7572                answer_cleanup(answer, olddata);
    76         } else {
     73        } else if (phoneid >= 0) {
    7774                /* The connection was accepted */
    7875                phone_connect(phoneid, &answer->sender->answerbox);
    7976                /* Set 'phone hash' as arg5 of response */
    8077                IPC_SET_ARG5(answer->data, (sysarg_t) &TASK->phones[phoneid]);
     78        } else {
     79                IPC_SET_RETVAL(answer->data, ELIMIT);
    8180        }
    8281
     
    8685
    8786sysipc_ops_t ipc_m_connect_to_me_ops = {
    88         .request_preprocess = null_request_preprocess,
     87        .request_preprocess = request_preprocess,
    8988        .request_forget = null_request_forget,
    9089        .request_process = request_process,
  • kernel/generic/src/ipc/sysipc.c

    r9ef1b79b r5d3ed34  
    4040#include <ipc/sysipc.h>
    4141#include <ipc/sysipc_ops.h>
     42#include <ipc/sysipc_priv.h>
    4243#include <ipc/irq.h>
    4344#include <ipc/ipcrsc.h>
     
    157158 *
    158159 */
    159 static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
     160int answer_preprocess(call_t *answer, ipc_data_t *olddata)
    160161{
    161162        int rc = EOK;
Note: See TracChangeset for help on using the changeset viewer.