[sgen] binary protocol on windows
authorVlad Brezae <brezaevlad@gmail.com>
Tue, 29 Nov 2016 22:06:55 +0000 (00:06 +0200)
committerVlad Brezae <brezaevlad@gmail.com>
Tue, 13 Dec 2016 18:44:05 +0000 (20:44 +0200)
mono/sgen/sgen-protocol.c
mono/sgen/sgen-protocol.h

index 8b9c432961fee581d76dc597dd08f7179617c72e..a399aa088da2fbe59635d443d777a79200698986 100644 (file)
 
 #include <errno.h>
 #include <string.h>
-#ifdef HAVE_UNISTD_H
+#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
 #include <fcntl.h>
+#elif defined(HOST_WIN32)
+#include <windows.h>
 #endif
 
-/* FIXME Implement binary protocol IO on systems that don't have unistd */
-#ifdef HAVE_UNISTD_H
+#if defined(HOST_WIN32)
+static const HANDLE invalid_file_value = INVALID_HANDLE_VALUE;
 /* If valid, dump binary protocol to this file */
+static HANDLE binary_protocol_file = INVALID_HANDLE_VALUE;
+#else
+static const int invalid_file_value = -1;
 static int binary_protocol_file = -1;
+#endif
 
 /* We set this to -1 to indicate an exclusive lock */
 static volatile int binary_protocol_use_count = 0;
@@ -90,6 +96,7 @@ binary_protocol_open_file (gboolean assert_on_failure)
        else
                filename = filename_or_prefix;
 
+#if defined(HAVE_UNISTD_H)
        do {
                binary_protocol_file = open (filename, O_CREAT | O_WRONLY, 0644);
                if (binary_protocol_file == -1) {
@@ -107,26 +114,29 @@ binary_protocol_open_file (gboolean assert_on_failure)
                        ftruncate (binary_protocol_file, 0);
                }
        } while (binary_protocol_file == -1);
+#elif defined(HOST_WIN32)
+       binary_protocol_file = CreateFileA (filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+#else
+       g_error ("sgen binary protocol: not supported");
+#endif
 
-       if (binary_protocol_file == -1 && assert_on_failure)
+       if (binary_protocol_file == invalid_file_value && assert_on_failure)
                g_error ("sgen binary protocol: failed to open file");
 
        if (file_size_limit > 0)
                free_filename (filename);
 }
-#endif
 
 void
 binary_protocol_init (const char *filename, long long limit)
 {
-#ifdef HAVE_UNISTD_H
        file_size_limit = limit;
 
        /* Original name length + . + pid length in hex + null terminator */
        filename_or_prefix = g_strdup_printf ("%s", filename);
        binary_protocol_open_file (FALSE);
 
-       if (binary_protocol_file == -1) {
+       if (binary_protocol_file == invalid_file_value) {
                /* Another process owns the file, try adding the pid suffix to the filename */
                gint32 pid = mono_process_current_pid ();
                g_free (filename_or_prefix);
@@ -139,29 +149,24 @@ binary_protocol_init (const char *filename, long long limit)
                g_free (filename_or_prefix);
 
        binary_protocol_header (PROTOCOL_HEADER_CHECK, PROTOCOL_HEADER_VERSION, SIZEOF_VOID_P, G_BYTE_ORDER == G_LITTLE_ENDIAN);
-#else
-       g_error ("sgen binary protocol: not supported");
-#endif
 }
 
 gboolean
 binary_protocol_is_enabled (void)
 {
-#ifdef HAVE_UNISTD_H
-       return binary_protocol_file != -1;
-#else
-       return FALSE;
-#endif
+       return binary_protocol_file != invalid_file_value;
 }
 
-#ifdef HAVE_UNISTD_H
-
 static void
 close_binary_protocol_file (void)
 {
+#if defined(HAVE_UNISTD_H)
        while (close (binary_protocol_file) == -1 && errno == EINTR)
                ;
-       binary_protocol_file = -1;
+#elif defined(HOST_WIN32)
+       CloseHandle (binary_protocol_file);
+#endif
+       binary_protocol_file = invalid_file_value;
 }
 
 static gboolean
@@ -220,6 +225,7 @@ binary_protocol_flush_buffer (BinaryProtocolBuffer *buffer)
        g_assert (buffer->index > 0);
 
        while (written < to_write) {
+#if defined(HAVE_UNISTD_H)
                ret = write (binary_protocol_file, buffer->buffer + written, to_write - written);
                if (ret >= 0)
                        written += ret;
@@ -227,6 +233,13 @@ binary_protocol_flush_buffer (BinaryProtocolBuffer *buffer)
                        continue;
                else
                        close_binary_protocol_file ();
+#elif defined(HOST_WIN32)
+               int tmp_written;
+               if (WriteFile (binary_protocol_file, buffer->buffer + written, to_write - written, &tmp_written, NULL))
+                       written += tmp_written;
+               else
+                       close_binary_protocol_file ();
+#endif
        }
 
        current_file_size += buffer->index;
@@ -253,7 +266,6 @@ binary_protocol_check_file_overflow (void)
 
        binary_protocol_open_file (TRUE);
 }
-#endif
 
 /*
  * Flushing buffers takes an exclusive lock, so it must only be done when the world is
@@ -265,13 +277,12 @@ binary_protocol_check_file_overflow (void)
 gboolean
 binary_protocol_flush_buffers (gboolean force)
 {
-#ifdef HAVE_UNISTD_H
        int num_buffers = 0, i;
        BinaryProtocolBuffer *header;
        BinaryProtocolBuffer *buf;
        BinaryProtocolBuffer **bufs;
 
-       if (binary_protocol_file == -1)
+       if (binary_protocol_file == invalid_file_value)
                return FALSE;
 
        if (!force && !try_lock_exclusive ())
@@ -302,10 +313,8 @@ binary_protocol_flush_buffers (gboolean force)
                unlock_exclusive ();
 
        return TRUE;
-#endif
 }
 
-#ifdef HAVE_UNISTD_H
 static BinaryProtocolBuffer*
 binary_protocol_get_buffer (int length)
 {
@@ -326,16 +335,14 @@ binary_protocol_get_buffer (int length)
 
        return new_buffer;
 }
-#endif
 
 static void
 protocol_entry (unsigned char type, gpointer data, int size)
 {
-#ifdef HAVE_UNISTD_H
        int index;
        BinaryProtocolBuffer *buffer;
 
-       if (binary_protocol_file == -1)
+       if (binary_protocol_file == invalid_file_value)
                return;
 
        if (sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()))
@@ -363,7 +370,6 @@ protocol_entry (unsigned char type, gpointer data, int size)
        g_assert (index <= BINARY_PROTOCOL_BUFFER_SIZE);
 
        unlock_recursive ();
-#endif
 }
 
 #define TYPE_INT int
index adefb98070bd5538b5d4a50442c311ef68dac853..3fe848878ec8e212ef60bf6ab411e5b3f3306706 100644 (file)
 #define BINARY_PROTOCOL_NO_MATCH (-1)
 #define BINARY_PROTOCOL_MATCH (-2)
 
-/* We pack all protocol structs by default unless specified otherwise */
-#ifndef PROTOCOL_STRUCT_ATTR
-#ifdef __GNUC__
-#define PROTOCOL_STRUCT_ATTR __attribute__ ((packed))
-#else
-#define PROTOCOL_STRUCT_ATTR
-#endif
-#endif
-
 #define PROTOCOL_ID(method) method ## _id
 #define PROTOCOL_STRUCT(method) method ## _struct
 #define CLIENT_PROTOCOL_NAME(method) sgen_client_ ## method
@@ -80,6 +71,19 @@ enum {
 #include "sgen-protocol-def.h"
 };
 
+/* We pack all protocol structs by default unless specified otherwise */
+#ifndef PROTOCOL_STRUCT_ATTR
+
+#define PROTOCOL_PACK_STRUCTS
+
+#if defined(__GNUC__)
+#define PROTOCOL_STRUCT_ATTR __attribute__ ((packed))
+#else
+#define PROTOCOL_STRUCT_ATTR
+#endif
+
+#endif
+
 #define BEGIN_PROTOCOL_ENTRY0(method)
 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
        typedef struct PROTOCOL_STRUCT_ATTR { \
@@ -147,7 +151,15 @@ enum {
 #define END_PROTOCOL_ENTRY_FLUSH
 #define END_PROTOCOL_ENTRY_HEAVY
 
+#if defined(_MSC_VER) && defined(PROTOCOL_PACK_STRUCTS)
+#pragma pack(push)
+#pragma pack(1)
+#endif
 #include "sgen-protocol-def.h"
+#if defined(_MSC_VER) && defined(PROTOCOL_PACK_STRUCTS)
+#pragma pack(pop)
+#undef PROTOCOL_PACK_STRUCTS
+#endif
 
 /* missing: finalizers, roots, non-store wbarriers */