2005-09-27 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / io-layer / wapi-private.h
index 03f1f19fe0a5bd6ac054a1429aa1d258c2094d9c..5dc0e6360732ab36004c9347d9e0538c85203d74 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <mono/io-layer/handles.h>
 #include <mono/io-layer/io.h>
-#include <mono/io-layer/daemon-private.h>
 
 /* Catch this here rather than corrupt the shared data at runtime */
 #if MONO_SIZEOF_SUNPATH==0
@@ -25,7 +24,7 @@
 /* Increment this whenever an incompatible change is made to the
  * shared handle structure.
  */
-#define _WAPI_HANDLE_VERSION 1
+#define _WAPI_HANDLE_VERSION 7
 
 typedef enum {
        WAPI_HANDLE_UNUSED=0,
@@ -39,33 +38,59 @@ typedef enum {
        WAPI_HANDLE_FIND,
        WAPI_HANDLE_PROCESS,
        WAPI_HANDLE_PIPE,
-       WAPI_HANDLE_COUNT,
+       WAPI_HANDLE_NAMEDMUTEX,
+       WAPI_HANDLE_COUNT
 } WapiHandleType;
 
+extern const char *_wapi_handle_typename[];
+
+#define _WAPI_SHARED_HANDLE(type) (type == WAPI_HANDLE_PROCESS || \
+                                  type == WAPI_HANDLE_NAMEDMUTEX)
+
+#define _WAPI_FD_HANDLE(type) (type == WAPI_HANDLE_FILE || \
+                              type == WAPI_HANDLE_CONSOLE || \
+                              type == WAPI_HANDLE_SOCKET || \
+                              type == WAPI_HANDLE_PIPE)
+
+#define _WAPI_SHARED_NAMESPACE(type) (type == WAPI_HANDLE_NAMEDMUTEX)
+
+typedef struct 
+{
+       gchar name[MAX_PATH + 1];
+} WapiSharedNamespace;
+
 typedef enum {
        WAPI_HANDLE_CAP_WAIT=0x01,
        WAPI_HANDLE_CAP_SIGNAL=0x02,
        WAPI_HANDLE_CAP_OWN=0x04,
+       WAPI_HANDLE_CAP_SPECIAL_WAIT=0x08
 } WapiHandleCapability;
 
 struct _WapiHandleOps 
 {
-       void (*close_shared)(gpointer handle);
-       void (*close_private)(gpointer handle);
+       void (*close)(gpointer handle, gpointer data);
 
        /* SignalObjectAndWait */
        void (*signal)(gpointer signal);
 
        /* Called by WaitForSingleObject and WaitForMultipleObjects,
-        * with the handle locked
+        * with the handle locked (shared handles aren't locked.)
+        * Returns TRUE if ownership was established, false otherwise.
         */
-       void (*own_handle)(gpointer handle);
+       gboolean (*own_handle)(gpointer handle);
 
        /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
         * handle in question is "ownable" (ie mutexes), to see if the current
         * thread already owns this handle
         */
        gboolean (*is_owned)(gpointer handle);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+        * if the handle in question needs a special wait function
+        * instead of using the normal handle signal mechanism.
+        * Returns the WaitForSingleObject return code.
+        */
+       guint32 (*special_wait)(gpointer handle, guint32 timeout);
 };
 
 #include <mono/io-layer/event-private.h>
@@ -76,10 +101,18 @@ struct _WapiHandleOps
 #include <mono/io-layer/thread-private.h>
 #include <mono/io-layer/process-private.h>
 
-/* Shared threads don't seem to work yet */
-#undef _POSIX_THREAD_PROCESS_SHARED
+struct _WapiHandle_shared_ref
+{
+       /* This will be split 16:16 with the shared file segment in
+        * the top half, when I implement space increases
+        */
+       guint32 offset;
+};
 
-struct _WapiHandleShared
+#define _WAPI_HANDLE_INITIAL_COUNT 4096
+#define _WAPI_HEADROOM 16
+
+struct _WapiHandleUnshared
 {
        WapiHandleType type;
        guint ref;
@@ -95,89 +128,76 @@ struct _WapiHandleShared
                struct _WapiHandle_mutex mutex;
                struct _WapiHandle_sem sem;
                struct _WapiHandle_socket sock;
+               struct _WapiHandle_shared_ref shared;
+
+               /* Move thread data into the private set, while
+                * problems with cleaning up shared handles are fixed
+                */
                struct _WapiHandle_thread thread;
-               struct _WapiHandle_process process;
        } u;
 };
 
-#define _WAPI_HANDLES_PER_SEGMENT 4096
-#define _WAPI_HANDLE_INVALID (gpointer)-1
-
-#define _WAPI_SHM_SCRATCH_SIZE 512000
-
-/*
- * This is the layout of the shared scratch data.  When the data array
- * is filled, it will be expanded by _WAPI_SHM_SCRATCH_SIZE
- * bytes. (scratch data is always copied out of the shared memory, so
- * it doesn't matter that the mapping will move around.)
- */
-struct _WapiHandleScratch
+struct _WapiHandleSharedMetadata
 {
-       guint32 data_len;
-
-       /* This is set to TRUE by the daemon.  It determines whether a
-        * resize will go via mremap() or just realloc().
-        */
-       gboolean is_shared;
-       guchar scratch_data[0];
+       volatile guint32 offset;
+       guint32 timestamp;
+       volatile gboolean signalled;
 };
 
-/*
- * This is the layout of the shared memory segments.  When the handles
- * array is filled, another shared memory segment will be allocated
- * with the same structure.  This is to avoid having the shared memory
- * potentially move if it is resized and remapped.
- *
- * Note that the additional segments have the same structure, but only
- * the handle array is used.
- */
-struct _WapiHandleShared_list
+struct _WapiHandleShared
 {
-       guchar daemon[MONO_SIZEOF_SUNPATH];
-       _wapi_daemon_status daemon_running;
+       WapiHandleType type;
+       gboolean stale;
        
-#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED != -1
-       mono_mutex_t signal_mutex;
-       pthread_cond_t signal_cond;
-#endif
-
-       /* This holds the number of segments */
-       guint32 num_segments;
-       struct _WapiHandleShared handles[_WAPI_HANDLES_PER_SEGMENT];
+       union
+       {
+               /* Leave this one while the thread is in the private
+                * set, so the shared space doesn't change size
+                */
+               struct _WapiHandle_thread thread;
+               struct _WapiHandle_process process;
+               struct _WapiHandle_namedmutex namedmutex;
+       } u;
 };
 
-struct _WapiHandlePrivate
+#define _WAPI_SHARED_SEM_NAMESPACE 0
+#define _WAPI_SHARED_SEM_COLLECTION 1
+#define _WAPI_SHARED_SEM_SHARE 2
+#define _WAPI_SHARED_SEM_HANDLE 3
+#define _WAPI_SHARED_SEM_COUNT 8       /* Leave some future expansion space */
+
+struct _WapiHandleSharedLayout
 {
-       WapiHandleType type;
+       volatile guint32 signal_count;
+       volatile guint32 collection_count;
+       volatile key_t sem_key;
+       
+       struct _WapiHandleSharedMetadata metadata[_WAPI_HANDLE_INITIAL_COUNT];
+       struct _WapiHandleShared handles[_WAPI_HANDLE_INITIAL_COUNT];
+};
 
-       union 
-       {
-               struct _WapiHandlePrivate_event event;
-               struct _WapiHandlePrivate_file file;
-               struct _WapiHandlePrivate_find find;
-               struct _WapiHandlePrivate_mutex mutex;
-               struct _WapiHandlePrivate_sem sem;
-               struct _WapiHandlePrivate_socket sock;
-               struct _WapiHandlePrivate_thread thread;
-               struct _WapiHandlePrivate_process process;
-       } u;
+#define _WAPI_FILESHARE_SIZE 102400
+
+struct _WapiFileShare
+{
+       dev_t device;
+       ino_t inode;
+       pid_t opened_by_pid;
+       guint32 sharemode;
+       guint32 access;
+       guint32 handle_refs;
+       guint32 timestamp;
 };
 
-/* Per-process handle info. For lookup convenience, each segment and
- * index matches the corresponding shared data.
- *
- * Note that the additional segments have the same structure, but only
- * the handle array is used.
- */
-struct _WapiHandlePrivate_list
+struct _WapiFileShareLayout
 {
-#if !defined(_POSIX_THREAD_PROCESS_SHARED) || _POSIX_THREAD_PROCESS_SHARED == -1
-       mono_mutex_t signal_mutex;
-       pthread_cond_t signal_cond;
-#endif
+       guint32 hwm;
        
-       struct _WapiHandlePrivate handles[_WAPI_HANDLES_PER_SEGMENT];
+       struct _WapiFileShare share_info[_WAPI_FILESHARE_SIZE];
 };
 
 
+
+#define _WAPI_HANDLE_INVALID (gpointer)-1
+
 #endif /* _WAPI_PRIVATE_H_ */