2009-02-10 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / io-layer / wapi-private.h
index 2a7203c693704f81f2022a24f4fa1f32adc4cc65..830405684b4f040fdff18dc7085f66a61bd3b7e5 100644 (file)
@@ -4,7 +4,7 @@
  * Author:
  *     Dick Porter (dick@ximian.com)
  *
- * (C) 2002 Ximian, Inc.
+ * (C) 2002-2006 Novell, Inc.
  */
 
 #ifndef _WAPI_PRIVATE_H_
 
 #include <config.h>
 #include <glib.h>
+#include <sys/stat.h>
 
 #include <mono/io-layer/handles.h>
 #include <mono/io-layer/io.h>
-#include <mono/io-layer/daemon-private.h>
-
-/* for non-GCC compilers where Glib gives an empty pretty function 
- * macro create one that gives file & line number instead
- */
-#ifndef __GNUC__
-#undef G_GNUC_PRETTY_FUNCTION
-#define STRINGIZE_HELPER(exp) #exp
-#define STRINGIZE(exp) STRINGIZE_HELPER(exp)
-#define G_GNUC_PRETTY_FUNCTION __FILE__ "(" STRINGIZE(__LINE__) ")"
-#endif
 
 /* Catch this here rather than corrupt the shared data at runtime */
 #if MONO_SIZEOF_SUNPATH==0
@@ -35,7 +25,7 @@
 /* Increment this whenever an incompatible change is made to the
  * shared handle structure.
  */
-#define _WAPI_HANDLE_VERSION 3
+#define _WAPI_HANDLE_VERSION 12
 
 typedef enum {
        WAPI_HANDLE_UNUSED=0,
@@ -49,53 +39,71 @@ typedef enum {
        WAPI_HANDLE_FIND,
        WAPI_HANDLE_PROCESS,
        WAPI_HANDLE_PIPE,
+       WAPI_HANDLE_NAMEDMUTEX,
+       WAPI_HANDLE_NAMEDSEM,
+       WAPI_HANDLE_NAMEDEVENT,
        WAPI_HANDLE_COUNT
 } WapiHandleType;
 
-#define _WAPI_SHARED_NAMESPACE(type) (type==WAPI_HANDLE_MUTEX)
+extern const char *_wapi_handle_typename[];
 
-typedef struct 
-{
-       guint32 name;
-} WapiSharedNamespace;
+#define _WAPI_SHARED_HANDLE(type) (type == WAPI_HANDLE_PROCESS || \
+                                  type == WAPI_HANDLE_NAMEDMUTEX || \
+                                  type == WAPI_HANDLE_NAMEDSEM || \
+                                  type == WAPI_HANDLE_NAMEDEVENT)
+
+#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 || \
+                                     type == WAPI_HANDLE_NAMEDSEM || \
+                                     type == WAPI_HANDLE_NAMEDEVENT)
 
-/* The boolean is for distinguishing between a zeroed struct being not
- * as yet assigned, and one containing a valid fd 0.  It's also used
- * to signal that a previously-good fd has been reused behind our
- * back, so we need to invalidate the handle that thought it owned the
- * fd.
- */
 typedef struct 
 {
-       int fd;
-       gboolean assigned;
-} WapiFDMapped;
-
+       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_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);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+        * if the handle in question needs some preprocessing before the
+        * signal wait.
+        */
+       void (*prewait)(gpointer handle);
 };
 
 #include <mono/io-layer/event-private.h>
@@ -106,10 +114,17 @@ 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;
+};
+
+#define _WAPI_HANDLE_INITIAL_COUNT 256
 
-struct _WapiHandleShared
+struct _WapiHandleUnshared
 {
        WapiHandleType type;
        guint ref;
@@ -126,89 +141,67 @@ struct _WapiHandleShared
                struct _WapiHandle_sem sem;
                struct _WapiHandle_socket sock;
                struct _WapiHandle_thread thread;
-               struct _WapiHandle_process process;
+               struct _WapiHandle_shared_ref shared;
        } 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 _WapiHandleShared
 {
-       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[MONO_ZERO_ARRAY_LENGTH];
+       WapiHandleType type;
+       guint32 timestamp;
+       guint32 handle_refs;
+       volatile gboolean signalled;
+       
+       union
+       {
+               struct _WapiHandle_process process;
+               struct _WapiHandle_namedmutex namedmutex;
+               struct _WapiHandle_namedsem namedsem;
+               struct _WapiHandle_namedevent namedevent;
+       } u;
 };
 
-/*
- * 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
+#define _WAPI_SHARED_SEM_NAMESPACE 0
+/*#define _WAPI_SHARED_SEM_COLLECTION 1*/
+#define _WAPI_SHARED_SEM_FILESHARE 2
+#define _WAPI_SHARED_SEM_SHARED_HANDLES 3
+#define _WAPI_SHARED_SEM_PROCESS_COUNT_LOCK 6
+#define _WAPI_SHARED_SEM_PROCESS_COUNT 7
+#define _WAPI_SHARED_SEM_COUNT 8       /* Leave some future expansion space */
+
+struct _WapiHandleSharedLayout
 {
-       guchar daemon[MONO_SIZEOF_SUNPATH];
-       _wapi_daemon_status daemon_running;
-       guint32 fd_offset_table_size;
+       volatile guint32 collection_count;
+       volatile key_t sem_key;
        
-#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];
+       struct _WapiHandleShared handles[_WAPI_HANDLE_INITIAL_COUNT];
 };
 
-struct _WapiHandlePrivate
-{
-       WapiHandleType type;
+#define _WAPI_FILESHARE_SIZE 102400
 
-       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;
+struct _WapiFileShare
+{
+#ifdef WAPI_FILE_SHARE_PLATFORM_EXTRA_DATA
+       WAPI_FILE_SHARE_PLATFORM_EXTRA_DATA
+#endif
+       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_ */