/[rtmk]/rtmk/ipc-port.c
ViewVC logotype

Diff of /rtmk/ipc-port.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7 by jrydberg, Sat Feb 16 15:17:15 2002 UTC revision 1.8 by jrydberg, Wed Feb 20 20:04:42 2002 UTC
# Line 1  Line 1 
1  /* ??? ports  /* Communication ports.
2     Copyright 1999, 2000, 2001, 2002 Johan Rydberg, jrydberg@rtmk.org.     Copyright 1999, 2000, 2001, 2002 Johan Rydberg, jrydberg@rtmk.org.
3    
4  This program is free software; you can redistribute it and/or modify  This program is free software; you can redistribute it and/or modify
# Line 30  static struct kmem_cache *port_cache; Line 30  static struct kmem_cache *port_cache;
30  static struct ipc_port *port_template;  static struct ipc_port *port_template;
31    
32  /* Initialize ports.  */  /* Initialize ports.  */
   
33  void  void
34  ipc_port_init (void)  ipc_port_init (void)
35  {  {
# Line 45  ipc_port_init (void) Line 44  ipc_port_init (void)
44    
45    port_template->ref_count = 1;    port_template->ref_count = 1;
46    port_template->active_p = true;    port_template->active_p = true;
47      port_template->pset = 0;
48    
49    /* ??? can we initialize the thread lock here?  */    /* ??? can we initialize the thread lock here?  */
50  }  }
# Line 52  ipc_port_init (void) Line 52  ipc_port_init (void)
52    
53  /* Create a new IPC port.  The port is return in PORTP.    /* Create a new IPC port.  The port is return in PORTP.  
54     Returns standard kernel return code.  */     Returns standard kernel return code.  */
   
55  kern_return_t  kern_return_t
56  ipc_port_create (struct ipc_port **portp)  ipc_port_create (struct ipc_port **portp)
57  {  {
# Line 64  ipc_port_create (struct ipc_port **portp Line 63  ipc_port_create (struct ipc_port **portp
63    
64    *port = *port_template;    *port = *port_template;
65    
66      queue_init (&port->pset_members);
67    thread_lock_init (&port->lock, true, true);    thread_lock_init (&port->lock, true, true);
68    ipc_tqueue_init (&port->waiting_threads);    ipc_tqueue_init (&port->waiting_threads);
69    ipc_tqueue_init (&port->blocked_threads);    ipc_tqueue_init (&port->blocked_threads);
# Line 85  ipc_port_create_receive (struct ipc_port Line 85  ipc_port_create_receive (struct ipc_port
85  }  }
86    
87  /* Allocate a new port.  Receive rights are returned in PORTP.  */  /* Allocate a new port.  Receive rights are returned in PORTP.  */
   
88  kern_return_t  kern_return_t
89  port_allocate (struct task *task, rtmk_port_t *portp)  port_allocate (struct task *task, rtmk_port_t *portp)
90  {  {
# Line 93  port_allocate (struct task *task, rtmk_p Line 92  port_allocate (struct task *task, rtmk_p
92    return ipc_port_create ((struct ipc_port **) portp);    return ipc_port_create ((struct ipc_port **) portp);
93  }  }
94    
95    /* Allocate a new named port.  We fail if name already exits.  */
96  kern_return_t  kern_return_t
97  port_allocate_name (struct task *task, rtmk_port_t name)  port_allocate_name (struct task *task, rtmk_port_t name)
98  {  {
# Line 111  port_allocate_name (struct task *task, r Line 111  port_allocate_name (struct task *task, r
111    return KERN_SUCCESS;    return KERN_SUCCESS;
112  }  }
113    
114    /* Allocate a new port set.  When created the port set does not
115       contain any members.  Return receive rights in PSETP.  */
116    kern_return_t
117    port_set_allocate (struct task *task, rtmk_port_t *psetp)
118    {
119      struct ipc_port *pset;
120      kern_return_t kr;
121    
122      kr = ipc_port_create (& pset);
123      if (kr)
124        return kr;
125      pset->is_pset_p = 1;
126      *psetp = (rtmk_port_t) pset;
127      return 0;
128    }
129    
130    /* Insert PORT into PORT_SET.  If PORT_SET is NULL, we remove
131       PORT from the port set it currently belongs to.  */
132    kern_return_t
133    port_move_member (struct task *task, struct ipc_port *port,
134                      struct ipc_port *pset)
135    {
136      if (! port)
137        return KERN_INVALID_ARGUMENT;
138    
139      if (pset)
140        {
141          if (! pset->is_pset_p)
142            return KERN_INVALID_ARGUMENT;
143          
144          /* If port is already a member of a port set we
145             remove the port from it and insert into new.  */
146          if (port->pset)
147            {
148              queue_remove (&port->pset->pset_members, port,
149                            struct ipc_port *, link);
150              port->pset = 0;
151            }
152    
153          queue_enter (& pset->pset_members, port, struct ipc_port *, link);
154          port->pset = pset;
155        }
156      else
157        {
158          if (! port->pset)
159            return KERN_INVALID_ARGUMENT;
160    
161          queue_remove (&port->pset->pset_members, port,
162                        struct ipc_port *, link);
163          port->pset = 0;
164        }
165      return KERN_SUCCESS;
166    }
167    
168  /* Inserts into TASK the caller's right for PORT. RIGHT_NAME is name in  /* Inserts into TASK the caller's right for PORT. RIGHT_NAME is name in
169     TASK's IPC object.  RIGHT_TYPE specifies right type.  */     TASK's IPC object.  RIGHT_TYPE specifies right type.  */
170  kern_return_t  kern_return_t
171  port_insert_right (struct task *task, struct ipc_port *port,  port_insert_right (struct task *task, struct ipc_port *port,
172                     rtmk_port_name_t right_name, rtmk_port_type_t right_type)                     rtmk_port_name_t right_name, rtmk_port_type_t right_type)
173  {  {
174    /* ??? lock object.  */    kern_return_t kr;
175    return  
176      ipc_object_insert (task->ipc_object, port, right_type, right_name);    ipc_object_lock (task->ipc_object);
177    /* ??? unlock object.  */    kr = ipc_object_insert (task->ipc_object, port, right_type, right_name);
178      ipc_object_unlock (task->ipc_object);
179      return kr;
180    }
181    
182    /* Removes TASK's rights for NAME.  The name becomes immediately
183       available for reuse.  */
184    kern_return_t
185    port_destroy (struct task *task, rtmk_port_name_t name)
186    {
187      struct ipc_entry *entry;
188      kern_return_t kr;
189    
190      ipc_object_lock (task->ipc_object);
191      kr = ipc_object_remove (task->ipc_object, &entry, name);
192      if (! kr)
193        {
194          ipc_object_unlock (task->ipc_object);
195          return kr;
196        }
197      assert (entry && entry->ie_port);
198      entry->ie_port->active_p = 0;
199      ipc_object_unlock (task->ipc_object);
200    
201      kmem_cache_free (ipc_entry_cache, entry);
202      return KERN_SUCCESS;
203    }
204    
205    /* Syscall version of function above.  */
206    struct port_destroy_args
207    {
208      rtmk_port_t task_name;
209      rtmk_port_name_t name;
210    };
211    
212    kern_return_t
213    syscall_port_destroy (struct port_destroy_args *a)
214    {
215      struct ipc_entry *entry;
216      struct task *task;
217      kern_return_t kr;
218      
219      ipc_object_lock (THREAD_CURRENT()->task->ipc_object);
220      kr = ipc_object_lookup (THREAD_CURRENT()->task->ipc_object, a->task_name,
221                              &entry);
222      if (kr != KERN_SUCCESS)
223        {
224          ipc_object_unlock (THREAD_CURRENT()->task->ipc_object);
225          return kr;
226        }
227    
228      if (entry->ie_port->kobject.type != IPC_KOBJECT_TYPE_TASK)
229        {
230          ipc_object_unlock (THREAD_CURRENT()->task->ipc_object);
231          return KERN_INVALID_TASK;
232        }
233      task = (struct task *) entry->ie_port->kobject.port;
234      ipc_object_unlock (THREAD_CURRENT()->task->ipc_object);
235    
236      return port_destroy (task, a->name);
237  }  }
238    
239  /* Create a new kernel port.  This port have not message queue since  /* Create a new kernel port.  This port have not message queue since

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26