Skip to content

Commit

Permalink
[System.IO][runtime] Import INotify CoreFX FileSystemWatcher
Browse files Browse the repository at this point in the history
System.Native icalls now live in metadata/pal-icalls.c|h
  • Loading branch information
alexischr committed Jul 16, 2018
1 parent b5071e8 commit 686e423
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 46 deletions.
2 changes: 2 additions & 0 deletions mcs/class/System/corefx.unix.sources
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
../../../external/corefx/src/Common/src/Interop/Unix/*.cs
corefx/Unix/Interop.cs
corefx/Unix/Interop.Read.cs
51 changes: 51 additions & 0 deletions mcs/class/System/corefx/Unix/Interop.Read.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

// This file reiimplements CoreFX source file 'src/Common/src/Interop/Unix/System.Native/Interop.Read.cs'

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System;

internal static partial class Interop
{
internal static partial class Sys
{
static Sys ()
{
Interop.mono_pal_init ();
}

/// <summary>
/// Reads a number of bytes from an open file descriptor into a specified buffer.
/// </summary>
/// <param name="fd">The open file descriptor to try to read from</param>
/// <param name="buffer">The buffer to read info into</param>
/// <param name="count">The size of the buffer</param>
/// <returns>
/// Returns the number of bytes read on success; otherwise, -1 is returned
/// Note - on fail. the position of the stream may change depending on the platform; consult man 2 read for more info
/// </returns>
internal static unsafe int Read (SafeFileHandle fd, byte* buffer, int count)
{
int bytes_read = -1;
bool release = false;
try {
fd.DangerousAddRef (ref release);
do {
bytes_read = Read (fd.DangerousGetHandle (), buffer, count);
} while (bytes_read < 0 && Marshal.GetLastWin32Error () == (int) Interop.Error.EINTR);
}
finally {
if (release)
fd.DangerousRelease ();
}
return bytes_read;
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe int Read (IntPtr fd, byte* buffer, int count);
}
}
11 changes: 11 additions & 0 deletions mcs/class/System/corefx/Unix/Interop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.InteropServices;

internal static partial class Interop
{
[DllImport("__Internal")]
internal static extern void mono_pal_init ();
}
1 change: 0 additions & 1 deletion mcs/class/System/unix_net_4_x_System.dll.sources
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Stat.cs
../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Poll.cs
../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Open.cs
../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Read.cs
../../../external/corefx/src/Common/src/Interop/Unix/System.Native/Interop.Close.cs
../../../external/corefx/src/Common/src/System/Net/ContextAwareResult.Unix.cs
Internal.Cryptography/OidLookup.Managed.cs
4 changes: 3 additions & 1 deletion mono/metadata/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ libmono_system_native_la_SOURCES = \
../../external/corefx/src/Native/Unix/System.Native/pal_tcpstate.c \
../../external/corefx/src/Native/Unix/System.Native/pal_tcpstate.h \
../../external/corefx/src/Native/Unix/System.Native/pal_random.c \
../../external/corefx/src/Native/Unix/System.Native/pal_random.h
../../external/corefx/src/Native/Unix/System.Native/pal_random.h \
pal-icalls.h \
pal-icalls.c

libmono_system_native_la_CFLAGS = -I$(abs_top_srcdir)/external/corefx/src/Native/Unix/Common -I$(abs_top_srcdir)/external/corefx/src/Native/Unix/System.Native -Wno-typedef-redefinition

Expand Down
42 changes: 9 additions & 33 deletions mono/metadata/filewatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ ves_icall_System_IO_FSW_SupportsFSW (void)
if (getenv ("MONO_DARWIN_USE_KQUEUE_FSW"))
return 3; /* kqueue */
else
return 6; /* FSEvent */
return 6; /* CoreFX */
#elif defined(HAVE_SYS_INOTIFY_H) && !defined(TARGET_ANDROID)
return 6; /* CoreFX */
#elif HAVE_KQUEUE
return 3; /* kqueue */
#else
Expand All @@ -72,11 +74,13 @@ ves_icall_System_IO_FSW_SupportsFSW (void)
int inotify_instance;
char *err;

#if defined (TARGET_ANDROID)
inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
if (inotify_instance != -1) {
close (inotify_instance);
return 5; /* inotify */
}
#endif

fam_module = mono_dl_open ("libgamin-1.so", MONO_DL_LAZY, NULL);
if (fam_module == NULL) {
Expand All @@ -85,14 +89,14 @@ ves_icall_System_IO_FSW_SupportsFSW (void)
}

if (fam_module == NULL)
return 0;
return 0; /* DefaultWatcher */

err = mono_dl_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
g_free (err);
if (FAMNextEvent == NULL)
return 0;

return lib_used;
return lib_used; /* DefaultWatcher */
#endif
}

Expand Down Expand Up @@ -132,6 +136,7 @@ ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
}
#endif

#if defined(TARGET_ANDROID)
#ifndef HAVE_SYS_INOTIFY_H
int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
{
Expand Down Expand Up @@ -213,6 +218,7 @@ ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
return inotify_rm_watch (fd, watch_descriptor);
}
#endif
#endif

#if HAVE_KQUEUE

Expand Down Expand Up @@ -265,34 +271,6 @@ ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer change

#endif /* #if HAVE_KQUEUE */

#if defined(__APPLE__)

#include <CoreFoundation/CFRunLoop.h>

static void
interrupt_CFRunLoop (gpointer data)
{
g_assert (data);
CFRunLoopStop(data);
}

void
ves_icall_CoreFX_Interop_RunLoop_CFRunLoopRun (void)
{
gpointer runloop_ref = CFRunLoopGetCurrent();
gboolean interrupted;
mono_thread_info_install_interrupt (interrupt_CFRunLoop, runloop_ref, &interrupted);

if (interrupted)
return;

MONO_ENTER_GC_SAFE;
CFRunLoopRun();
MONO_EXIT_GC_SAFE;

mono_thread_info_uninstall_interrupt (&interrupted);
}

#ifdef HOST_IOS

MONO_API char* SystemNative_RealPath(const char* path)
Expand All @@ -307,5 +285,3 @@ MONO_API void SystemNative_Sync(void)
}

#endif // HOST_IOS

#endif /* #if defined(__APPLE__) */
3 changes: 0 additions & 3 deletions mono/metadata/filewatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,10 @@ int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descrip

int ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq, gpointer changelist, int nchanges, gpointer eventlist, int nevents);

#if defined(__APPLE__)
void ves_icall_CoreFX_Interop_RunLoop_CFRunLoopRun (void);
#ifdef HOST_IOS // This will obsoleted by System.Native as soon as it's ported to iOS
MONO_API char* SystemNative_RealPath(const char* path);
MONO_API void SystemNative_Sync (void);
#endif
#endif

G_END_DECLS

Expand Down
7 changes: 2 additions & 5 deletions mono/metadata/icall-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@
* Limitations: "out" and "ref" arguments are not supported yet.
*/

#if defined(__APPLE__)
ICALL_TYPE(CLR_INTEROP, "Interop/RunLoop", CLR_INTEROP_1)
ICALL(CLR_INTEROP_1, "CFRunLoopRun", ves_icall_CoreFX_Interop_RunLoop_CFRunLoopRun)
#endif

ICALL_TYPE(NATIVEMETHODS, "Microsoft.Win32.NativeMethods", NATIVEMETHODS_1)
HANDLES(ICALL(NATIVEMETHODS_1, "CloseProcess", ves_icall_Microsoft_Win32_NativeMethods_CloseProcess))
HANDLES(ICALL(NATIVEMETHODS_2, "GetCurrentProcess", ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess))
Expand Down Expand Up @@ -342,10 +337,12 @@ ICALL(FAMW_1, "InternalFAMNextEvent", ves_icall_System_IO_FAMW_InternalFAMNextEv
ICALL_TYPE(FILEW, "System.IO.FileSystemWatcher", FILEW_4)
ICALL(FILEW_4, "InternalSupportsFSW", ves_icall_System_IO_FSW_SupportsFSW)

#if defined (TARGET_ANDROID)
ICALL_TYPE(INOW, "System.IO.InotifyWatcher", INOW_1)
ICALL(INOW_1, "AddWatch", ves_icall_System_IO_InotifyWatcher_AddWatch)
ICALL(INOW_2, "GetInotifyInstance", ves_icall_System_IO_InotifyWatcher_GetInotifyInstance)
ICALL(INOW_3, "RemoveWatch", ves_icall_System_IO_InotifyWatcher_RemoveWatch)
#endif

ICALL_TYPE(KQUEM, "System.IO.KqueueMonitor", KQUEM_1)
ICALL(KQUEM_1, "kevent_notimeout", ves_icall_System_IO_KqueueMonitor_kevent_notimeout)
Expand Down
2 changes: 1 addition & 1 deletion mono/metadata/marshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ mono_free_lparray (MonoArray *array, gpointer* nativeArray);
void
mono_marshal_ftnptr_eh_callback (guint32 gchandle);

void
MONO_PAL_API void
mono_marshal_set_last_error (void);

guint
Expand Down
78 changes: 78 additions & 0 deletions mono/metadata/pal-icalls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* \file
* System.Native PAL internal calls
* Adapter code between the Mono runtime and the CoreFX Platform Abstraction Layer (PAL)
* Copyright 2018 Microsoft
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/

#include <config.h>
#include <glib.h>
#include "pal_io.h"
#include "mono/utils/mono-threads-api.h"
#include "mono/utils/atomic.h"

#include "pal-icalls.h"

/*
* mono_pal_init:
*
* Initializes Mono's usage of the PAL (probably just by registering the necessary internal calls).
* This is called only from managed code, by any Interop.* classes that need to use the code here.
* The function may be called multiple times.
*
*/
void
mono_pal_init (void)
{
volatile static gboolean module_initialized = FALSE;
if (mono_atomic_cas_i32 (&module_initialized, TRUE, FALSE) == FALSE) {
mono_add_internal_call ("Interop/Sys::Read", ves_icall_Interop_Sys_Read);

#if defined(__APPLE__)
mono_add_internal_call ("Interop/RunLoop::CFRunLoopRun", ves_icall_Interop_RunLoop_CFRunLoopRun);
#endif
}

}

gint32
ves_icall_Interop_Sys_Read (intptr_t fd, gchar* buffer, gint32 count)
{
gint32 result;
MONO_ENTER_GC_SAFE;
result = SystemNative_Read (fd, buffer, count);
mono_marshal_set_last_error ();
MONO_EXIT_GC_SAFE;
return result;
}

#if defined(__APPLE__)

#include <CoreFoundation/CFRunLoop.h>

static void
interrupt_CFRunLoop (gpointer data)
{
g_assert (data);
CFRunLoopStop (data);
}

void
ves_icall_Interop_RunLoop_CFRunLoopRun (void)
{
gpointer runloop_ref = CFRunLoopGetCurrent ();
gboolean interrupted;
mono_thread_info_install_interrupt (interrupt_CFRunLoop, runloop_ref, &interrupted);

if (interrupted)
return;

MONO_ENTER_GC_SAFE;
CFRunLoopRun ();
MONO_EXIT_GC_SAFE;

mono_thread_info_uninstall_interrupt (&interrupted);
}

#endif
26 changes: 26 additions & 0 deletions mono/metadata/pal-icalls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* \file
* System.Native PAL internal calls
* Adapter code between the Mono runtime and the CoreFX Platform Abstraction Layer (PAL)
* Copyright 2018 Microsoft
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/

#ifndef __MONO_METADATA_PAL_ICALLS_H__
#define __MONO_METADATA_PAL_ICALLS_H__

#include "metadata.h"
#include "class-internals.h"

MONO_API void mono_pal_init (void);

extern void mono_marshal_set_last_error (void);
gint32 ves_icall_Interop_Sys_Read (intptr_t fd, gchar* buffer, gint32 count);

#if defined(__APPLE__)
extern void mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted);
extern void mono_thread_info_uninstall_interrupt (gboolean *interrupted);
void ves_icall_Interop_RunLoop_CFRunLoopRun (void);
#endif

#endif
2 changes: 2 additions & 0 deletions mono/metadata/pal_config.h
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#include <config.h>

#define MONO 1
3 changes: 3 additions & 0 deletions mono/utils/mono-compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ typedef SSIZE_T ssize_t;
/* Used to mark internal functions used by the profiler modules */
#define MONO_PROFILER_API MONO_API

/* Used to mark internal functions used by the CoreFX PAL library */
#define MONO_PAL_API MONO_API

#ifdef __GNUC__
#define MONO_ALWAYS_INLINE __attribute__ ((__always_inline__))
#elif defined(_MSC_VER)
Expand Down
4 changes: 2 additions & 2 deletions mono/utils/mono-threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,10 +479,10 @@ mono_thread_info_tls_set (THREAD_INFO_TYPE *info, MonoTlsKey key, gpointer value
void
mono_thread_info_exit (gsize exit_code);

void
MONO_PAL_API void
mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted);

void
MONO_PAL_API void
mono_thread_info_uninstall_interrupt (gboolean *interrupted);

MonoThreadInfoInterruptToken*
Expand Down

0 comments on commit 686e423

Please sign in to comment.