Prex Home / Browse Source - Prex Version: 0.9.0

root/sys/ipc/object.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. object_create
  2. object_lookup
  3. object_valid
  4. object_find
  5. object_deallocate
  6. object_destroy
  7. object_cleanup
  8. object_init

   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] */