2005-09-27 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / io-layer / wapi-private.h
index 1a3d28d8b52243113d2d8864e9a0e66b06dc6433..5dc0e6360732ab36004c9347d9e0538c85203d74 100644 (file)
+/*
+ * wapi-private.h:  internal definitions of handles and shared memory layout
+ *
+ * Author:
+ *     Dick Porter (dick@ximian.com)
+ *
+ * (C) 2002 Ximian, Inc.
+ */
+
 #ifndef _WAPI_PRIVATE_H_
 #define _WAPI_PRIVATE_H_
 
 #include <config.h>
 #include <glib.h>
 
-#include "mono/io-layer/handles.h"
+#include <mono/io-layer/handles.h>
+#include <mono/io-layer/io.h>
+
+/* Catch this here rather than corrupt the shared data at runtime */
+#if MONO_SIZEOF_SUNPATH==0
+#error configure failed to discover size of unix socket path
+#endif
+
+/* Increment this whenever an incompatible change is made to the
+ * shared handle structure.
+ */
+#define _WAPI_HANDLE_VERSION 7
 
 typedef enum {
+       WAPI_HANDLE_UNUSED=0,
        WAPI_HANDLE_FILE,
        WAPI_HANDLE_CONSOLE,
        WAPI_HANDLE_THREAD,
        WAPI_HANDLE_SEM,
        WAPI_HANDLE_MUTEX,
        WAPI_HANDLE_EVENT,
-       WAPI_HANDLE_COUNT,
+       WAPI_HANDLE_SOCKET,
+       WAPI_HANDLE_FIND,
+       WAPI_HANDLE_PROCESS,
+       WAPI_HANDLE_PIPE,
+       WAPI_HANDLE_NAMEDMUTEX,
+       WAPI_HANDLE_COUNT
 } WapiHandleType;
 
-struct _WapiHandleOps 
+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 
 {
-       /* All handle types */
-       void (*close)(WapiHandle *handle);
+       gchar name[MAX_PATH + 1];
+} WapiSharedNamespace;
 
-       /* File, console and pipe handles */
-       WapiFileType (*getfiletype)(void);
-       
-       /* File and console handles */
-       gboolean (*readfile)(WapiHandle *handle, gpointer buffer,
-                            guint32 numbytes, guint32 *bytesread,
-                            WapiOverlapped *overlapped);
-       gboolean (*writefile)(WapiHandle *handle, gconstpointer buffer,
-                             guint32 numbytes, guint32 *byteswritten,
-                             WapiOverlapped *overlapped);
-       
-       /* File handles */
-       guint32 (*seek)(WapiHandle *handle, gint32 movedistance,
-                       gint32 *highmovedistance, WapiSeekMethod method);
-       gboolean (*setendoffile)(WapiHandle *handle);
-       guint32 (*getfilesize)(WapiHandle *handle, guint32 *highsize);
-       gboolean (*getfiletime)(WapiHandle *handle, WapiFileTime *create_time,
-                               WapiFileTime *last_access,
-                               WapiFileTime *last_write);
-       gboolean (*setfiletime)(WapiHandle *handle,
-                               const WapiFileTime *create_time,
-                               const WapiFileTime *last_access,
-                               const WapiFileTime *last_write);
-       
-       /* WaitForSingleObject */
-       gboolean (*wait)(WapiHandle *handle, WapiHandle *signal, guint32 ms);
+typedef enum {
+       WAPI_HANDLE_CAP_WAIT=0x01,
+       WAPI_HANDLE_CAP_SIGNAL=0x02,
+       WAPI_HANDLE_CAP_OWN=0x04,
+       WAPI_HANDLE_CAP_SPECIAL_WAIT=0x08
+} WapiHandleCapability;
 
-       /* WaitForMultipleObjects */
-       guint32 (*wait_multiple)(gpointer data);
+struct _WapiHandleOps 
+{
+       void (*close)(gpointer handle, gpointer data);
 
        /* SignalObjectAndWait */
-       void (*signal)(WapiHandle *signal);
+       void (*signal)(gpointer signal);
+
+       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+        * with the handle locked (shared handles aren't locked.)
+        * Returns TRUE if ownership was established, false otherwise.
+        */
+       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>
+#include <mono/io-layer/io-private.h>
+#include <mono/io-layer/mutex-private.h>
+#include <mono/io-layer/semaphore-private.h>
+#include <mono/io-layer/socket-private.h>
+#include <mono/io-layer/thread-private.h>
+#include <mono/io-layer/process-private.h>
+
+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 _WapiHandle
+#define _WAPI_HANDLE_INITIAL_COUNT 4096
+#define _WAPI_HEADROOM 16
+
+struct _WapiHandleUnshared
 {
        WapiHandleType type;
        guint ref;
        gboolean signalled;
-       struct _WapiHandleOps *ops;
+       mono_mutex_t signal_mutex;
+       pthread_cond_t signal_cond;
+       
+       union 
+       {
+               struct _WapiHandle_event event;
+               struct _WapiHandle_file file;
+               struct _WapiHandle_find find;
+               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;
+       } u;
 };
 
-#define _WAPI_HANDLE_INIT(_handle, _type, _ops)        G_STMT_START {\
-               _handle->type=_type;\
-               _handle->ref=1;\
-               _handle->signalled=FALSE;\
-               _handle->ops=&_ops;\
-       } G_STMT_END;
+struct _WapiHandleSharedMetadata
+{
+       volatile guint32 offset;
+       guint32 timestamp;
+       volatile gboolean signalled;
+};
+
+struct _WapiHandleShared
+{
+       WapiHandleType type;
+       gboolean stale;
+       
+       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;
+};
+
+#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
+{
+       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];
+};
+
+#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;
+};
+
+struct _WapiFileShareLayout
+{
+       guint32 hwm;
+       
+       struct _WapiFileShare share_info[_WAPI_FILESHARE_SIZE];
+};
+
+
+
+#define _WAPI_HANDLE_INVALID (gpointer)-1
 
 #endif /* _WAPI_PRIVATE_H_ */