* 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
/* 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,
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>
#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;
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_ */