|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/sys/ipc/object.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.
1 /*- 2 * Copyright (c) 2005-2008, Kohsuke Ohtani 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * object.c - object service 32 */ 33 34 /** 35 * IPC object: 36 * 37 * An object represents service, state, or policies etc. To manipulate 38 * objects, kernel provide 3 functions: create, destroy and lookup. 39 * Prex task will create an object to provide its services to other 40 * tasks. The tasks will communicate by sending a message to the 41 * object each other. In typical case, a server task creates an object 42 * and client tasks will send a request message to it. 43 * 44 * A substance of object is stored in kernel space, and so it's protected 45 * from user mode code. Usually, an object has a unique name within a 46 * system. Before a task sends a message to the specific object, it must 47 * obtain the object ID by looking up the name of the target object. 48 * 49 * A task can create a private object which does not have name. Since 50 * another task can not obtain the ID of such object, the IPC operations 51 * for the private object are limited to the threads in the same task. 52 * 53 * The object name started with '!' means that it is a protected object. 54 * The protected object can be created only by the task which has 55 * CAP_PROTSERV capability. Since this capability is given to the known 56 * system servers, the client task can always trust the object owner. 57 */ 58 59 #include <kernel.h> 60 #include <kmem.h> 61 #include <sched.h> 62 #include <task.h> 63 #include <ipc.h> 64 65 /* forward declarations */ 66 static object_t object_find(const char *); 67 68 static struct list object_list; /* list of all objects */ 69 70 /* 71 * Create a new object. 72 * 73 * The ID of the new object is stored in objp on success. 74 * The name of the object must be unique in the system. 75 * Or, the object can be created without name by setting 76 * NULL as name argument. This object can be used as a 77 * private object which can be accessed only by threads in 78 * same task. 79 */ 80 int 81 object_create(const char *name, object_t *objp) 82 { 83 struct object *obj = 0; 84 char str[MAXOBJNAME]; 85 int error; 86 87 if (name == NULL) 88 str[0] = '\0'; 89 else { 90 error = copyinstr(name, str, MAXOBJNAME); 91 if (error) 92 return error; 93 94 /* Check capability if name is protected object. */ 95 if (name[0] == '!' && !task_capable(CAP_PROTSERV)) 96 return EPERM; 97 } 98 sched_lock(); 99 100 if (curtask->nobjects >= MAXOBJECTS) { 101 sched_unlock(); 102 return EAGAIN; 103 } 104 /* 105 * Check user buffer first. This can reduce the error 106 * recovery for the subsequence resource allocations. 107 */ 108 if (copyout(&obj, objp, sizeof(obj))) { 109 sched_unlock(); 110 return EFAULT; 111 } 112 if (object_find(str) != NULL) { 113 sched_unlock(); 114 return EEXIST; 115 } 116 if ((obj = kmem_alloc(sizeof(*obj))) == NULL) { 117 sched_unlock(); 118 return ENOMEM; 119 } 120 if (name != NULL) 121 strlcpy(obj->name, str, MAXOBJNAME); 122 123 obj->owner = curtask; 124 queue_init(&obj->sendq); 125 queue_init(&obj->recvq); 126 list_insert(&curtask->objects, &obj->task_link); 127 curtask->nobjects++; 128 list_insert(&object_list, &obj->link); 129 copyout(&obj, objp, sizeof(obj)); 130 131 sched_unlock(); 132 return 0; 133 } 134 135 /* 136 * Search an object in the object name space. The object 137 * name must be null-terminated string. 138 */ 139 int 140 object_lookup(const char *name, object_t *objp) 141 { 142 object_t obj; 143 char str[MAXOBJNAME]; 144 int error; 145 146 error = copyinstr(name, str, MAXOBJNAME); 147 if (error) 148 return error; 149 150 sched_lock(); 151 obj = object_find(str); 152 sched_unlock(); 153 154 if (obj == NULL) 155 return ENOENT; 156 157 if (copyout(&obj, objp, sizeof(obj))) 158 return EFAULT; 159 return 0; 160 } 161 162 int 163 object_valid(object_t obj) 164 { 165 object_t tmp; 166 list_t n; 167 168 for (n = list_first(&object_list); n != &object_list; 169 n = list_next(n)) { 170 tmp = list_entry(n, struct object, link); 171 if (tmp == obj) 172 return 1; 173 } 174 return 0; 175 } 176 177 static object_t 178 object_find(const char *name) 179 { 180 object_t obj; 181 list_t n; 182 183 for (n = list_first(&object_list); n != &object_list; 184 n = list_next(n)) { 185 obj = list_entry(n, struct object, link); 186 if (!strncmp(obj->name, name, MAXOBJNAME)) 187 return obj; 188 } 189 return 0; 190 } 191 192 /* 193 * Deallocate an object-- the internal version of object_destory. 194 */ 195 static void 196 object_deallocate(object_t obj) 197 { 198 199 msg_abort(obj); 200 obj->owner->nobjects--; 201 list_remove(&obj->task_link); 202 list_remove(&obj->link); 203 kmem_free(obj); 204 } 205 206 /* 207 * Destroy an object. 208 * 209 * All pending messages related to the target object are 210 * automatically cancelled. 211 */ 212 int 213 object_destroy(object_t obj) 214 { 215 216 sched_lock(); 217 if (!object_valid(obj)) { 218 sched_unlock(); 219 return EINVAL; 220 } 221 if (obj->owner != curtask) { 222 sched_unlock(); 223 return EACCES; 224 } 225 object_deallocate(obj); 226 sched_unlock(); 227 return 0; 228 } 229 230 /* 231 * Clean up for task termination. 232 */ 233 void 234 object_cleanup(task_t task) 235 { 236 object_t obj; 237 238 while (!list_empty(&task->objects)) { 239 obj = list_entry(list_first(&task->objects), 240 struct object, task_link); 241 object_deallocate(obj); 242 } 243 } 244 245 void 246 object_init(void) 247 { 248 249 list_init(&object_list); 250 } /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |