15 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
16 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
17 |
|
|
18 |
|
#include <rtmk/ipc-return.h> |
19 |
#include "tm.h" |
#include "tm.h" |
20 |
|
|
21 |
#include "trace.h" |
#include "trace.h" |
22 |
#include "ipc-port.h" |
#include "ipc-port.h" |
23 |
|
#include "ipc-syscall.h" |
24 |
#include "vm-slab.h" |
#include "vm-slab.h" |
25 |
#include "task.h" |
#include "task.h" |
26 |
#include "thread.h" |
#include "thread.h" |
69 |
thread_lock_init (&port->lock, true, true); |
thread_lock_init (&port->lock, true, true); |
70 |
ipc_tqueue_init (&port->waiting_threads); |
ipc_tqueue_init (&port->waiting_threads); |
71 |
ipc_tqueue_init (&port->blocked_threads); |
ipc_tqueue_init (&port->blocked_threads); |
72 |
port->mqueue = ipc_mqueue_create (); |
ipc_mqueue_create (&port->mqueue); |
73 |
|
|
74 |
*portp = port; |
*portp = port; |
75 |
return KERN_SUCCESS; |
return KERN_SUCCESS; |
108 |
|
|
109 |
if (! free_p) |
if (! free_p) |
110 |
return; |
return; |
111 |
trace_printf ("implement"); |
ipc_mqueue_destroy (&port->mqueue); |
112 |
|
|
113 |
|
/* ??? what to do with port sets? */ |
114 |
|
|
115 |
|
assert (ipc_tqueue_empty (&port->waiting_threads)); |
116 |
|
assert (ipc_tqueue_empty (&port->blocked_threads)); |
117 |
|
kmem_cache_free (port_cache, port); |
118 |
} |
} |
119 |
|
|
120 |
/* Allocate a new port. Receive rights are returned in PORTP. */ |
/* Allocate a new port. Receive rights are returned in PORTP. */ |
218 |
port_destroy (struct task *task, rtmk_port_name_t name) |
port_destroy (struct task *task, rtmk_port_name_t name) |
219 |
{ |
{ |
220 |
struct ipc_entry *entry; |
struct ipc_entry *entry; |
221 |
|
struct ipc_port *port; |
222 |
|
struct thread *thread; |
223 |
kern_return_t kr; |
kern_return_t kr; |
224 |
|
SPL_T spl; |
225 |
|
|
226 |
ipc_object_lock (task->ipc_object); |
ipc_object_lock (task->ipc_object); |
227 |
kr = ipc_object_remove (task->ipc_object, &entry, name); |
kr = ipc_object_remove (task->ipc_object, &entry, name); |
228 |
if (! kr) |
if (kr) |
229 |
{ |
{ |
230 |
ipc_object_unlock (task->ipc_object); |
ipc_object_unlock (task->ipc_object); |
231 |
return kr; |
return kr; |
232 |
} |
} |
233 |
assert (entry && entry->ie_port); |
assert (entry && entry->ie_port); |
234 |
|
|
235 |
thread_lock_write (& entry->ie_port->lock); |
port = entry->ie_port; |
236 |
entry->ie_port->active_p = 0; |
thread_lock_write (& port->lock); |
237 |
thread_lock_unlock (& entry->ie_port->lock); |
port->active_p = 0; |
238 |
|
|
239 |
|
/* We go to SPLOFF here so that the callout thread will |
240 |
|
not be invoked. This should eliminate a race condition |
241 |
|
between dequeuing thread from list and the timeout |
242 |
|
function being called. ??? verify this. */ |
243 |
|
spl = SPLOFF (); |
244 |
|
while ((thread = ipc_tqueue_dequeue (&port->waiting_threads))) |
245 |
|
{ |
246 |
|
untimeout (timeout_receive, thread); |
247 |
|
thread->ipc_result = MSG_RECV_PORT_DIED; |
248 |
|
} |
249 |
|
|
250 |
|
while ((thread = ipc_tqueue_dequeue (&port->blocked_threads))) |
251 |
|
{ |
252 |
|
untimeout (timeout_send, thread); |
253 |
|
thread->ipc_result = MSG_SEND_INVALID_DST; |
254 |
|
} |
255 |
|
SPLON (spl); |
256 |
|
|
257 |
|
thread_lock_unlock (& port->lock); |
258 |
ipc_object_unlock (task->ipc_object); |
ipc_object_unlock (task->ipc_object); |
259 |
|
|
260 |
ipc_port_release (entry->ie_port); |
thread_wakeup ((int) port); |
261 |
|
ipc_port_release (port); |
262 |
|
|
263 |
kmem_cache_free (ipc_entry_cache, entry); |
kmem_cache_free (ipc_entry_cache, entry); |
264 |
return KERN_SUCCESS; |
return KERN_SUCCESS; |
400 |
ipc_port_create_kernel (void) |
ipc_port_create_kernel (void) |
401 |
{ |
{ |
402 |
struct ipc_port *port; |
struct ipc_port *port; |
403 |
|
kern_return_t kr; |
404 |
|
|
405 |
port = (struct ipc_port *) kmem_cache_alloc (port_cache); |
kr = ipc_port_create (& port); |
406 |
if (! port) |
if (kr) |
407 |
return 0; |
return 0L; |
|
|
|
|
*port = *port_template; |
|
|
|
|
|
thread_lock_init (&port->lock, true, true); |
|
408 |
port->rcvobject = TASK_KERNEL()->ipc_object; |
port->rcvobject = TASK_KERNEL()->ipc_object; |
|
|
|
409 |
return port; |
return port; |
410 |
} |
} |
411 |
|
|