Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset fdd4898 in mainline


Ignore:
Timestamp:
2011-08-17T09:08:36Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
9bf51e64
Parents:
5d0500c
Message:

Add IPC_M_STATE_CHANGE_AUTHORIZE.

  • This message is used when two clients of the same server task want to achieve certain change in their state but that state is maintained externally in the server.
  • The typical situation is passing some sort of handle from the donor task to the acceptor task.
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • abi/include/ipc/methods.h

    r5d0500c rfdd4898  
    171171#define IPC_M_DATA_READ  8
    172172
     173/** Authorize change of recipient's state in a third party task.
     174 * - ARG1 - user protocol defined data
     175 * - ARG2 - user protocol defined data
     176 * - ARG3 - user protocol defined data
     177 * - ARG5 - sender's phone to the third party task
     178 *
     179 * on EOK answer, the recipient must set:
     180 *
     181 * - ARG1 - recipient's phone to the third party task
     182 */
     183#define IPC_M_STATE_CHANGE_AUTHORIZE    9
     184
    173185/** Debug the recipient.
    174186 * - ARG1 - specifies the debug method (from udebug_method_t)
     
    176188 *
    177189 */
    178 #define IPC_M_DEBUG  9
     190#define IPC_M_DEBUG 10
    179191
    180192/** Last system IPC method */
  • kernel/generic/src/ipc/sysipc.c

    r5d0500c rfdd4898  
    4444#include <ipc/irq.h>
    4545#include <ipc/ipcrsc.h>
     46#include <ipc/event.h>
    4647#include <ipc/kbox.h>
    4748#include <synch/waitq.h>
     
    134135        case IPC_M_DATA_WRITE:
    135136        case IPC_M_DATA_READ:
     137        case IPC_M_STATE_CHANGE_AUTHORIZE:
    136138                return true;
    137139        default:
     
    164166        case IPC_M_DATA_WRITE:
    165167        case IPC_M_DATA_READ:
     168        case IPC_M_STATE_CHANGE_AUTHORIZE:
    166169                return true;
    167170        default:
     
    334337                free(answer->buffer);
    335338                answer->buffer = NULL;
     339        } else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
     340                if (!IPC_GET_RETVAL(answer->data)) {
     341                        /* The recipient authorized the change of state. */
     342                        phone_t *recipient_phone;
     343                        task_t *other_task_s;
     344                        task_t *other_task_r;
     345                        int rc;
     346
     347                        rc = phone_get(IPC_GET_ARG1(answer->data),
     348                            &recipient_phone);
     349                        if (rc != EOK) {
     350                                IPC_SET_RETVAL(answer->data, ENOENT);
     351                                return ENOENT;
     352                        }
     353
     354                        mutex_lock(&recipient_phone->lock);
     355                        if (recipient_phone->state != IPC_PHONE_CONNECTED) {
     356                                mutex_unlock(&recipient_phone->lock);
     357                                IPC_SET_RETVAL(answer->data, EINVAL);
     358                                return EINVAL;
     359                        }
     360
     361                        other_task_r = recipient_phone->callee->task;
     362                        other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
     363
     364                        /*
     365                         * See if both the sender and the recipient meant the
     366                         * same third party task.
     367                         */
     368                        if (other_task_r != other_task_s) {
     369                                IPC_SET_RETVAL(answer->data, EINVAL);
     370                                rc = EINVAL;
     371                        } else {
     372                                rc = event_task_notify_5(other_task_r,
     373                                    EVENT_TASK_STATE_CHANGE, false,
     374                                    IPC_GET_ARG1(*olddata),
     375                                    IPC_GET_ARG2(*olddata),
     376                                    IPC_GET_ARG3(*olddata),
     377                                    (sysarg_t) olddata->task,
     378                                    (sysarg_t) TASK);
     379                                IPC_SET_RETVAL(answer->data, rc);
     380                        }
     381
     382                        mutex_unlock(&recipient_phone->lock);
     383                        return rc;
     384                }
    336385        }
    337386       
     
    456505                }
    457506               
     507                break;
     508        }
     509        case IPC_M_STATE_CHANGE_AUTHORIZE: {
     510                phone_t *sender_phone;
     511                task_t *other_task_s;
     512
     513                if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
     514                        return ENOENT;
     515
     516                mutex_lock(&sender_phone->lock);
     517                if (sender_phone->state != IPC_PHONE_CONNECTED) {
     518                        mutex_unlock(&sender_phone->lock);
     519                        return EINVAL;
     520                }
     521
     522                other_task_s = sender_phone->callee->task;
     523
     524                mutex_unlock(&sender_phone->lock);
     525
     526                /* Remember the third party task hash. */
     527                IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
    458528                break;
    459529        }
Note: See TracChangeset for help on using the changeset viewer.