2 * Code to support inter-process sharing of handles.
4 * I thought of using an mmap()ed file for this. If linuxthreads
5 * supported PTHREAD_PROCESS_SHARED I would have done; however without
6 * that pthread support the only other inter-process IPC
7 * synchronisation option is a sysV semaphore, and if I'm going to use
8 * that I may as well take advantage of sysV shared memory too.
9 * Actually, semaphores seem to be buggy, or I was using them
10 * incorrectly :-). I've replaced the sysV semaphore with a shared
11 * integer controlled with Interlocked functions.
13 * mmap() files have the advantage of avoiding namespace collisions,
14 * but have the disadvantage of needing cleaning up, and also msync().
15 * sysV shared memory has a really stupid way of getting random key
16 * IDs, which can lead to collisions.
18 * I deliberately don't ever delete the shared memory: I'd like to
19 * have been able to set the shared memory segment to destroy itself
20 * on last close, but it doesn't support that. (Setting IPC_RMID on a
21 * segment causes subsequent shmat() with the same key to get a new
22 * segment :-( ). The function to delete the shared memory segment is
23 * only called from a debugging tool (mono/handles/shmdel).
25 * w32 processes do not have the POSIX parent-child relationship, so a
26 * process handle is available to any other process to find out exit
27 * status. Handles are destroyed when the last reference to them is
28 * closed. New handles can be created for long lasting items such as
29 * processes or threads, and also for named synchronisation objects so
30 * long as these haven't been deleted by having the last referencing
38 #include <sys/types.h>
43 #include <mono/io-layer/wapi.h>
44 #include <mono/io-layer/wapi-private.h>
45 #include <mono/io-layer/shared.h>
49 static gboolean shared;
51 gpointer _wapi_shm_attach (guint32 *scratch_size)
55 *scratch_size=getpagesize ()*100;
57 #ifndef DISABLE_SHARED_HANDLES
58 if(getenv ("MONO_DISABLE_SHM"))
62 g_message (G_GNUC_PRETTY_FUNCTION
63 ": Using process-private handles");
67 shm_seg=g_malloc0 (sizeof(struct _WapiHandleShared_list)+
69 #ifndef DISABLE_SHARED_HANDLES
77 * This is an attempt to get a unique key id. The
78 * first arg to ftok is a path, so when the config
79 * file support is done we should use that.
81 key=ftok (g_get_home_dir (), _WAPI_HANDLE_VERSION);
83 /* sysv shared mem is set to all zero when allocated,
84 * so we don't need to do any more initialisation here
86 shm_id=shmget (key, sizeof(struct _WapiHandleShared_list)+
87 *scratch_size, IPC_CREAT | 0600);
93 shm_seg=shmat (shm_id, NULL, 0);
94 if(shm_seg==(gpointer)-1) {
98 #endif /* DISABLE_SHARED_HANDLES */
104 void _wapi_shm_destroy (void)
106 #ifndef DISABLE_SHARED_HANDLES
111 * This is an attempt to get a unique key id. The
112 * first arg to ftok is a path, so when the config
113 * file support is done we should use that.
115 key=ftok (g_get_home_dir (), _WAPI_HANDLE_VERSION);
117 /* sysv shared mem is set to all zero when allocated,
118 * so we don't need to do any more initialisation here
120 shm_id=shmget (key, 0, 0600);
121 if(shm_id==-1 && errno==ENOENT) {
123 } else if (shm_id==-1) {
127 if(shmctl (shm_id, IPC_RMID, NULL)==-1) {
131 #endif /* DISABLE_SHARED_HANDLES */