source: mainline/kernel/generic/src/ipc/ops/conctmeto.c@ 813fc8c

Last change on this file since 813fc8c was 813fc8c, checked in by Jakub Jermar <jakub@…>, 7 years ago

Publish capability only after phone connects

In IPC_M_CONNECT_ME_TO it is desirable to publish the new phone
capability only after the phone gets connected. Otherwise we might have
open phones without capabilities and no way to hang them up in
ipc_cleanup().

  • Property mode set to 100644
File size: 4.7 KB
RevLine 
[f0defd2]1/*
[e8039a86]2 * Copyright (c) 2006 Ondrej Palkovsky
[48bcf49]3 * Copyright (c) 2012 Jakub Jermar
[f0defd2]4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup genericipc
31 * @{
32 */
33/** @file
34 */
35
36#include <ipc/sysipc_ops.h>
[e8039a86]37#include <ipc/ipc.h>
38#include <ipc/ipcrsc.h>
39#include <abi/errno.h>
40#include <arch.h>
[f0defd2]41
[b7fd2a0]42static errno_t request_preprocess(call_t *call, phone_t *phone)
[e8039a86]43{
[09d01f2]44 cap_handle_t phone_handle;
[b7fd2a0]45 errno_t rc = phone_alloc(TASK, &phone_handle);
[09d01f2]46 if (rc != EOK) {
[813fc8c]47 call->priv = -1;
[09d01f2]48 return rc;
49 }
[48bcf49]50
[813fc8c]51 /*
52 * The capability is now published, but the phone is not connected yet.
53 * The user cannot use it to send anything over it, in fact the
54 * userspace can only unpublish and free the capability at this point.
55 *
56 * We now proceed to test the capability is still there. We don't care
57 * if the user destroyed the old one and recreated a new published one
58 * of the same type under the same handle.
59 *
60 * If the capability is in place we temporarily unpublish it to make
61 * sure the user cannot fiddle with it while we are connecting.
62 */
63
64 kobject_t *phone_obj = cap_unpublish(TASK, phone_handle,
[48bcf49]65 KOBJECT_TYPE_PHONE);
[fb1f664]66 if (!phone_obj) {
67 /*
68 * Another thread of the same task can destroy the new
69 * capability before we manage to get a reference from it.
70 */
71 call->priv = -1;
72 return ENOENT;
73 }
[813fc8c]74
[48bcf49]75 /* Hand over phone_obj's reference to ARG5 */
76 IPC_SET_ARG5(call->data, (sysarg_t) phone_obj->phone);
[e8039a86]77
[813fc8c]78 /* Remember the handle */
79 call->priv = phone_handle;
80
[e8039a86]81 return EOK;
82}
83
[b7fd2a0]84static errno_t request_forget(call_t *call)
[b1e6269]85{
[48bcf49]86 cap_handle_t phone_handle = (cap_handle_t) call->priv;
[09d01f2]87
[813fc8c]88 if (phone_handle < 0)
[09d01f2]89 return EOK;
90
[48bcf49]91 /* Hand over reference from ARG5 to phone->kobject */
92 phone_t *phone = (phone_t *) IPC_GET_ARG5(call->data);
[813fc8c]93 /* Drop phone->kobject's reference */
[48bcf49]94 kobject_put(phone->kobject);
[813fc8c]95 cap_free(TASK, phone_handle);
96
[466e95f7]97 return EOK;
[b1e6269]98}
99
[b7fd2a0]100static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
[e8039a86]101{
[48bcf49]102 /* Hand over reference from ARG5 to phone */
[e8039a86]103 phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
104
[813fc8c]105 /*
106 * Get an extra reference and pass it in the answer data.
107 */
108 kobject_add_ref(phone->kobject);
109 IPC_SET_ARG5(answer->data, (sysarg_t) phone);
110
111 /* If the user accepted the call, connect */
[48bcf49]112 if (IPC_GET_RETVAL(answer->data) == EOK) {
113 /* Hand over reference from phone to the answerbox */
[c33f39f]114 (void) ipc_phone_connect(phone, &TASK->answerbox);
[48bcf49]115 } else {
116 kobject_put(phone->kobject);
117 }
[e8039a86]118
119 return EOK;
120}
121
[b7fd2a0]122static errno_t answer_process(call_t *answer)
[1b186ed]123{
[48bcf49]124 cap_handle_t phone_handle = (cap_handle_t) answer->priv;
[813fc8c]125 phone_t *phone = (phone_t *) IPC_GET_ARG5(answer->data);
[022d72ff]126
127 if (IPC_GET_RETVAL(answer->data)) {
[48bcf49]128 if (phone_handle >= 0) {
[022d72ff]129 /*
[813fc8c]130 * Cleanup the unpublished capability and drop
131 * phone->kobject's reference.
[022d72ff]132 */
[813fc8c]133 kobject_put(phone->kobject);
134 cap_free(TASK, phone_handle);
[022d72ff]135 }
[eab9689]136 } else {
[813fc8c]137 /*
138 * Publish the capability. Publishing the capability this late
139 * is important for ipc_cleanup() where we want to have a
140 * capability for each phone that wasn't hung up by the user.
141 */
142 cap_publish(TASK, phone_handle, phone->kobject);
143
[48bcf49]144 IPC_SET_ARG5(answer->data, phone_handle);
[eab9689]145 }
[a35b458]146
[1b186ed]147 return EOK;
148}
[e8039a86]149
150sysipc_ops_t ipc_m_connect_me_to_ops = {
151 .request_preprocess = request_preprocess,
[b1e6269]152 .request_forget = request_forget,
[f0defd2]153 .request_process = null_request_process,
[b1e6269]154 .answer_cleanup = null_answer_cleanup,
[e8039a86]155 .answer_preprocess = answer_preprocess,
[1b186ed]156 .answer_process = answer_process,
[f0defd2]157};
158
159/** @}
160 */
Note: See TracBrowser for help on using the repository browser.