This allow the removal of MONO_(PREPARE|FINISH)BLOCKING and MONO(PREPARE|FINISH)_RESET_BLOCKING, which were not explicit in their intent, leading to confusion. This also harmonize how the product and the runtime transition between thread states.
{
guint32 result;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
result = WaitForSingleObjectEx (handle, timeout, alertable);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return result;
}
ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
*ioerror = ERROR_SUCCESS;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, ioerror);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (!names) {
// If there's no array and no error, then return an empty array.
IncrementalFind *ifh = (IncrementalFind *)handle;
gint32 error;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (FindClose (ifh->find_handle) == FALSE){
error = GetLastError ();
} else
error = ERROR_SUCCESS;
g_free (ifh->utf8_path);
g_free (ifh);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return error;
}
gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
gboolean ret;
gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (sourceFileName)
utf16_sourceFileName = mono_string_chars (sourceFileName);
if (ret == FALSE)
*error = GetLastError ();
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return ret;
}
MonoBoolean overwrite, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
{
gint32 ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
{
gboolean result;
WIN32_FILE_ATTRIBUTE_DATA data;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
memset (stat, 0, sizeof (MonoIOStat));
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return result;
}
HANDLE ret;
int attributes, attrs;
gunichar2 *chars;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
chars = mono_string_chars (filename);
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
buffer = mono_array_addr (dest, guchar, dest_offset);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
result = ReadFile (handle, buffer, count, &n, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (!result) {
*error=GetLastError ();
}
buffer = mono_array_addr (src, guchar, src_offset);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
result = WriteFile (handle, buffer, count, &n, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (!result) {
*error=GetLastError ();
gint32 *error)
{
gint32 offset_hi;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return offset | ((gint64)offset_hi << 32);
}
ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
{
gint64 length;
guint32 length_hi;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return length | ((gint64)length_hi << 32);
}
const FILETIME *creation_filetime;
const FILETIME *last_access_filetime;
const FILETIME *last_write_filetime;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return(ret);
}
attr.bInheritHandle=TRUE;
attr.lpSecurityDescriptor=NULL;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=CreatePipe (read_handle, write_handle, &attr, 0);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if(ret==FALSE) {
*error = GetLastError ();
/* This is only used on Windows */
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if(ret==FALSE) {
*error = GetLastError ();
gint64 length, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error = GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
gint64 length, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
*error=ERROR_SUCCESS;
*error = GetLastError ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
//Support for io-layer free mmap'd files.
gint64 res;
char *path = mono_string_to_utf8 (string);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (stat (path, &buf) == -1)
res = -1;
else
g_free (path);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
struct stat buf;
int res;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = fstat (fd, &buf);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (res == -1)
return (gint64)-1;
return -1;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = kevent (*kq_ptr, changelist, nchanges, eventlist, nevents, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
{
guint32 result;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
result = WaitForSingleObjectEx (handle, timeout, alertable);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return result;
}
register_icall (mono_gchandle_new, "mono_gchandle_new", "uint32 object bool", TRUE);
register_icall (mono_marshal_isinst_with_cache, "mono_marshal_isinst_with_cache", "object object ptr ptr", FALSE);
register_icall (mono_marshal_ftnptr_eh_callback, "mono_marshal_ftnptr_eh_callback", "void uint32", TRUE);
- register_icall (mono_threads_prepare_blocking_unbalanced, "mono_threads_prepare_blocking_unbalanced", "ptr ptr", TRUE);
- register_icall (mono_threads_finish_blocking_unbalanced, "mono_threads_finish_blocking_unbalanced", "void ptr ptr", TRUE);
+ register_icall (mono_threads_enter_gc_safe_region_unbalanced, "mono_threads_enter_gc_safe_region_unbalanced", "ptr ptr", TRUE);
+ register_icall (mono_threads_exit_gc_safe_region_unbalanced, "mono_threads_exit_gc_safe_region_unbalanced", "void ptr ptr", TRUE);
mono_cominterop_init ();
mono_remoting_init ();
}
/*
- * cookie = mono_threads_prepare_blocking_unbalanced (ref dummy);
+ * cookie = mono_threads_enter_gc_safe_region_unbalanced (ref dummy);
*
* ret = method (...);
*
- * mono_threads_finish_blocking_unbalanced (cookie, ref dummy);
+ * mono_threads_exit_gc_safe_region_unbalanced (cookie, ref dummy);
*
* <interrupt check>
*
}
mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
- mono_mb_emit_icall (mb, mono_threads_prepare_blocking_unbalanced);
+ mono_mb_emit_icall (mb, mono_threads_enter_gc_safe_region_unbalanced);
mono_mb_emit_stloc (mb, coop_gc_var);
}
if (mono_threads_is_coop_enabled ()) {
mono_mb_emit_ldloc (mb, coop_gc_var);
mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
- mono_mb_emit_icall (mb, mono_threads_finish_blocking_unbalanced);
+ mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
}
/* Set LastError if needed */
g_assert (gchandle >= 0);
- mono_threads_reset_blocking_start_unbalanced (&stackdata);
+ mono_threads_enter_gc_unsafe_region_unbalanced (&stackdata);
exc = (MonoException*) mono_gchandle_get_target (gchandle);
* We pass TRUE instead of allow_interruption since we have to check for the
* StopRequested case below.
*/
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = WaitForSingleObjectEx (mon->entry_sem, waitms, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
* is private to this thread. Therefore even if the event was
* signalled before we wait, we still succeed.
*/
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = WaitForSingleObjectEx (event, ms, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
/* Reset the thread state fairly early, so we don't have to worry
* about the monitor error checking
/* Poll the event again, just in case it was signalled
* while we were trying to regain the monitor lock
*/
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = WaitForSingleObjectEx (event, 0, FALSE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
/* Pulse will have popped our event from the queue if it signalled
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- MONO_PREPARE_RESET_BLOCKING;
+ MONO_ENTER_GC_UNSAFE;
result = callbacks.runtime_invoke (method, obj, params, exc, error);
- MONO_FINISH_RESET_BLOCKING;
+ MONO_EXIT_GC_UNSAFE;
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
g_assert (!mono_threads_is_coop_enabled ());
- MONO_PREPARE_RESET_BLOCKING;
+ MONO_ENTER_GC_UNSAFE;
method = mono_marshal_get_thunk_invoke_wrapper (method);
res = mono_compile_method (method);
- MONO_FINISH_RESET_BLOCKING;
+ MONO_EXIT_GC_UNSAFE;
return res;
}
static inline void
dynamic_image_lock (MonoDynamicImage *image)
{
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
mono_image_lock ((MonoImage*)image);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
static inline void
* polling system does not notify when the socket is closed */
mono_threadpool_ms_io_remove_socket (GPOINTER_TO_INT (sock));
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
closesocket (sock);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
gint32
return NULL;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
#ifdef HOST_WIN32
{
newsock = _wapi_accept (sock, NULL, 0);
#endif
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
*werror = 0;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_listen (sock, backlog);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret == SOCKET_ERROR)
*werror = WSAGetLastError ();
}
sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_getsockname (sock, (struct sockaddr *)sa, &salen);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret == SOCKET_ERROR) {
*werror = WSAGetLastError ();
sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
/* Note: linux returns just 2 for AF_UNIX. Always. */
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_getpeername (sock, (struct sockaddr *)sa, &salen);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret == SOCKET_ERROR) {
*werror = WSAGetLastError ();
return FALSE;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = mono_poll (pfds, 1, timeout);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_connect (sock, sa, sa_size);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
LOGDEBUG (g_message("%s: disconnecting from socket %p (reuse %d)", __func__, sock, reuse));
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
/* I _think_ the extension function pointers need to be looked
* up for each socket. FIXME: check the best way to store
ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, (gchar *)&disco_guid, sizeof (GUID),
(gchar *)&_wapi_disconnectex, sizeof (void *), &output_bytes, NULL, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret != 0) {
/* make sure that WSAIoctl didn't put crap in the
*/
_wapi_disconnectex = NULL;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
/*
* Use the SIO_GET_EXTENSION_FUNCTION_POINTER to
ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, (gchar *)&trans_guid, sizeof(GUID),
(gchar *)&_wapi_transmitfile, sizeof(void *), &output_bytes, NULL, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret != 0)
_wapi_transmitfile = NULL;
return;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (_wapi_disconnectex != NULL) {
if (!_wapi_disconnectex (sock, NULL, TF_REUSE_SOCKET, 0))
*werror = ERROR_NOT_SUPPORTED;
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted)
if (interrupted)
return 0;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
#ifdef HOST_WIN32
{
ret = _wapi_recv (sock, buf, count, recvflags);
#endif
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return 0;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = WSARecv (sock, wsabufs, count, &recv, &recvflags, NULL, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return 0;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_recvfrom (sock, buf, count, recvflags, sa, &sa_size);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return 0;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_send (sock, buf, count, sendflags);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return 0;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = WSASend (sock, wsabufs, count, &sent, sendflags, NULL, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return 0;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_sendto (sock, buf, count, sendflags, sa, sa_size);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = mono_poll (pfds, nfds, timeout);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
/* No need to deal with MulticastOption names here, because
* you cant getsockopt AddMembership or DropMembership (the
ret = _wapi_getsockopt (sock, system_level, system_name, &val, &valsize);
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret == SOCKET_ERROR) {
*werror = WSAGetLastError ();
valsize = mono_array_length (*byte_val);
buf = mono_array_addr (*byte_val, guchar, 0);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = _wapi_getsockopt (sock, system_level, system_name, buf, &valsize);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret == SOCKET_ERROR)
*werror = WSAGetLastError ();
return;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
/* Currently, the values for how (recv=0, send=1, both=2) match the BSD API */
ret = _wapi_shutdown (sock, how);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
o_len = mono_array_length (output);
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = WSAIoctl (sock, code, i_buffer, i_len, o_buffer, o_len, &output_bytes, NULL, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret == SOCKET_ERROR) {
*werror = WSAGetLastError ();
g_free (address);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
switch (family) {
case AF_INET: {
g_assert_not_reached ();
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (!ret)
return FALSE;
return FALSE;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = TransmitFile (sock, file, 0, 0, NULL, &buffers, flags);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
return FALSE;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
CloseHandle (file);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return ret;
}
MONO_OBJECT_SETREF (ares, handle, (MonoObject*) wait_handle);
}
mono_monitor_exit ((MonoObject*) ares);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
ac = (MonoAsyncCall*) ares->object_data;
}
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
WaitForSingleObject (sem, timeout != -1 ? end - now : timeout);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
domain->cleanup_semaphore = NULL;
*/
THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
CloseHandle (internal->start_notify);
internal->start_notify = NULL;
mono_thread_set_state (cur_thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=WaitForSingleObjectEx (handle, ms, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_clr_state (cur_thread, ThreadState_WaitSleepJoin);
start = (ms == -1) ? 0 : mono_100ns_ticks ();
do {
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (multiple)
ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable);
else
ret = WaitForSingleObjectEx (handles [0], ms, alertable);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret != WAIT_IO_COMPLETION)
break;
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = SignalObjectAndWait (toSignal, toWait, ms, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if(ret==WAIT_FAILED) {
/* See the comment in build_wait_tids() */
count++;
}
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if(ret==WAIT_FAILED) {
/* See the comment in build_wait_tids() */
static gint64 last_keepalive;
gint64 msecs;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
do {
again:
}
} while ((res > 0 && total < len) || (res == -1 && get_last_sock_error () == MONO_EINTR));
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return total;
}
static int
socket_transport_accept (int socket_fd)
{
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
conn_fd = accept (socket_fd, NULL, NULL);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (conn_fd == -1) {
fprintf (stderr, "debugger-agent: Unable to listen on %d\n", socket_fd);
{
int res;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
do {
res = send (conn_fd, data, len, 0);
} while (res == -1 && get_last_sock_error () == MONO_EINTR);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (res != len)
return FALSE;
FD_ZERO (&readfds);
FD_SET (sfd, &readfds);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = select (sfd + 1, &readfds, NULL, NULL, &tv);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (res == 0) {
fprintf (stderr, "debugger-agent: Timed out waiting to connect.\n");
if (sfd == -1)
continue;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = connect (sfd, &sockaddr.addr, sock_len);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (res != -1)
break; /* Success */
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
close (sfd);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
}
if (rp == 0) {
#else
shutdown (conn_fd, SHUT_RD);
shutdown (listen_fd, SHUT_RDWR);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
close (listen_fd);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
#endif
}
*dummy = NULL;
/* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
* return the right cookie. */
- return mono_threads_cookie_for_reset_blocking_start (mono_thread_info_current ());
+ return mono_threads_enter_gc_unsafe_region_cookie (mono_thread_info_current ());
} else {
*dummy = orig;
/* thread state (BLOCKING|RUNNING) -> RUNNING */
- return mono_threads_reset_blocking_start (dummy);
+ return mono_threads_enter_gc_unsafe_region (dummy);
}
}
}
/* it won't do anything if cookie is NULL
* thread state RUNNING -> (RUNNING|BLOCKING) */
- mono_threads_reset_blocking_end (cookie, dummy);
+ mono_threads_exit_gc_unsafe_region (cookie, dummy);
if (orig != domain) {
if (!orig)
{
gpointer res;
- MONO_PREPARE_RESET_BLOCKING_UNBALANCED;
+ MONO_ENTER_GC_UNSAFE_UNBALANCED;
MonoError error;
mono_interruption_checkpoint_from_trampoline ();
- MONO_FINISH_RESET_BLOCKING_UNBALANCED;
+ MONO_EXIT_GC_UNSAFE_UNBALANCED;
return res;
}
if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER &&
(info->d.icall.func == mono_thread_interruption_checkpoint ||
- info->d.icall.func == mono_threads_finish_blocking_unbalanced)) {
+ info->d.icall.func == mono_threads_exit_gc_safe_region_unbalanced)) {
/* These wrappers are called from the wrapper for the polling function, leading to potential stack overflow */
if (cfg->verbose_level > 1)
printf ("SKIPPING SAFEPOINTS for wrapper %s\n", cfg->method->name);
if (mono_os_mutex_trylock (&mutex->m) == 0)
return 0;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = mono_os_mutex_lock (&mutex->m);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
{
gint res;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = mono_os_cond_wait (&cond->c, &mutex->m);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
{
gint res;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = mono_os_cond_timedwait (&cond->c, &mutex->m, timeout_ms);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
{
gint res;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = mono_os_sem_wait (&sem->s, flags);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
{
gint res;
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
res = mono_os_sem_timedwait (&sem->s, timeout_ms, flags);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return res;
}
For further explanation of what can and can't be done in GC unsafe mode:
http://www.mono-project.com/docs/advanced/runtime/docs/coop-suspend/#gc-unsafe-mode
-
*/
-#define MONO_BEGIN_GC_UNSAFE \
+#define MONO_ENTER_GC_UNSAFE \
do { \
- gpointer __dummy; \
- gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region (&__dummy) \
+ gpointer __gc_unsafe_dummy; \
+ gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region (&__gc_unsafe_dummy) \
-#define MONO_END_GC_UNSAFE \
- mono_threads_exit_gc_unsafe_region (__gc_unsafe_cookie, &__dummy); \
+#define MONO_EXIT_GC_UNSAFE \
+ mono_threads_exit_gc_unsafe_region (__gc_unsafe_cookie, &__gc_unsafe_dummy); \
} while (0)
-#define MONO_BEGIN_GC_SAFE \
+#define MONO_ENTER_GC_SAFE \
do { \
- gpointer __dummy; \
- gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region (&__dummy) \
+ gpointer __gc_safe_dummy; \
+ gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region (&__gc_safe_dummy) \
-#define MONO_END_GC_SAFE \
- mono_threads_exit_gc_safe_region (__gc_safe_cookie, &__dummy); \
+#define MONO_EXIT_GC_SAFE \
+ mono_threads_exit_gc_safe_region (__gc_safe_cookie, &__gc_safe_dummy); \
} while (0)
MONO_END_DECLS
}
gpointer
-mono_threads_prepare_blocking (gpointer *stackdata)
+mono_threads_enter_gc_safe_region (gpointer *stackdata)
{
gpointer cookie;
if (!mono_threads_is_coop_enabled ())
return NULL;
- cookie = mono_threads_prepare_blocking_unbalanced (stackdata);
+ cookie = mono_threads_enter_gc_safe_region_unbalanced (stackdata);
#ifdef ENABLE_CHECKED_BUILD_GC
if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
}
gpointer
-mono_threads_prepare_blocking_unbalanced (gpointer *stackdata)
+mono_threads_enter_gc_safe_region_unbalanced (gpointer *stackdata)
{
MonoThreadInfo *info;
}
void
-mono_threads_finish_blocking (gpointer cookie, gpointer *stackdata)
+mono_threads_exit_gc_safe_region (gpointer cookie, gpointer *stackdata)
{
if (!mono_threads_is_coop_enabled ())
return;
coop_tls_pop (cookie);
#endif
- mono_threads_finish_blocking_unbalanced (cookie, stackdata);
+ mono_threads_exit_gc_safe_region_unbalanced (cookie, stackdata);
}
void
-mono_threads_finish_blocking_unbalanced (gpointer cookie, gpointer *stackdata)
+mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata)
{
static gboolean warned_about_bad_transition;
MonoThreadInfo *info;
}
}
-gpointer
-mono_threads_cookie_for_reset_blocking_start (MonoThreadInfo *info)
+void
+mono_threads_assert_gc_safe_region (void)
{
- g_assert (mono_threads_is_coop_enabled ());
-
-#ifdef ENABLE_CHECKED_BUILD_GC
- if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
- coop_tls_push (info);
-#endif
-
- return info;
+ MONO_REQ_GC_SAFE_MODE;
}
gpointer
-mono_threads_reset_blocking_start (gpointer *stackdata)
+mono_threads_enter_gc_unsafe_region (gpointer *stackdata)
{
gpointer cookie;
if (!mono_threads_is_coop_enabled ())
return NULL;
- cookie = mono_threads_reset_blocking_start_unbalanced (stackdata);
+ cookie = mono_threads_enter_gc_unsafe_region_unbalanced (stackdata);
#ifdef ENABLE_CHECKED_BUILD_GC
if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
}
gpointer
-mono_threads_reset_blocking_start_unbalanced (gpointer *stackdata)
+mono_threads_enter_gc_unsafe_region_unbalanced (gpointer *stackdata)
{
MonoThreadInfo *info;
return info;
}
+gpointer
+mono_threads_enter_gc_unsafe_region_cookie (MonoThreadInfo *info)
+{
+ g_assert (mono_threads_is_coop_enabled ());
+
+#ifdef ENABLE_CHECKED_BUILD_GC
+ if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
+ coop_tls_push (info);
+#endif
+
+ return info;
+}
+
void
-mono_threads_reset_blocking_end (gpointer cookie, gpointer *stackdata)
+mono_threads_exit_gc_unsafe_region (gpointer cookie, gpointer *stackdata)
{
if (!mono_threads_is_coop_enabled ())
return;
coop_tls_pop (cookie);
#endif
- mono_threads_reset_blocking_end_unbalanced (cookie, stackdata);
+ mono_threads_exit_gc_unsafe_region_unbalanced (cookie, stackdata);
}
void
-mono_threads_reset_blocking_end_unbalanced (gpointer cookie, gpointer *stackdata)
+mono_threads_exit_gc_unsafe_region_unbalanced (gpointer cookie, gpointer *stackdata)
{
if (!mono_threads_is_coop_enabled ())
return;
g_assert (((MonoThreadInfo *)cookie) == mono_thread_info_current_unchecked ());
}
- mono_threads_prepare_blocking_unbalanced (stackdata);
+ mono_threads_enter_gc_safe_region_unbalanced (stackdata);
+}
+
+void
+mono_threads_assert_gc_unsafe_region (void)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
}
void
if (mono_threads_is_coop_enabled ())
mono_polling_required = 0;
}
-
-gpointer
-mono_threads_enter_gc_unsafe_region (gpointer* stackdata)
-{
- if (!mono_threads_is_coop_enabled ())
- return NULL;
-
- return mono_threads_reset_blocking_start (stackdata);
-}
-
-void
-mono_threads_exit_gc_unsafe_region (gpointer cookie, gpointer* stackdata)
-{
- if (!mono_threads_is_coop_enabled ())
- return;
-
- mono_threads_reset_blocking_end (cookie, stackdata);
-}
-
-void
-mono_threads_assert_gc_unsafe_region (void)
-{
- MONO_REQ_GC_UNSAFE_MODE;
-}
-
-gpointer
-mono_threads_enter_gc_safe_region (gpointer *stackdata)
-{
- if (!mono_threads_is_coop_enabled ())
- return NULL;
-
- return mono_threads_prepare_blocking (stackdata);
-}
-
-void
-mono_threads_exit_gc_safe_region (gpointer cookie, gpointer *stackdata)
-{
- if (!mono_threads_is_coop_enabled ())
- return;
-
- mono_threads_finish_blocking (cookie, stackdata);
-}
-
-void
-mono_threads_assert_gc_safe_region (void)
-{
- MONO_REQ_GC_SAFE_MODE;
-}
#include <glib.h>
#include "checked-build.h"
+#include "mono-threads-api.h"
G_BEGIN_DECLS
void
mono_threads_state_poll (void);
-gpointer
-mono_threads_prepare_blocking (gpointer *stackdata);
-
-void
-mono_threads_finish_blocking (gpointer cookie, gpointer *stackdata);
-
-gpointer
-mono_threads_reset_blocking_start (gpointer *stackdata);
-
-void
-mono_threads_reset_blocking_end (gpointer cookie, gpointer *stackdata);
-
static inline void
mono_threads_safepoint (void)
{
mono_threads_state_poll ();
}
-#define MONO_PREPARE_BLOCKING \
- MONO_REQ_GC_NOT_CRITICAL; \
- do { \
- gpointer __dummy; \
- gpointer __blocking_cookie = mono_threads_prepare_blocking (&__dummy)
-
-#define MONO_FINISH_BLOCKING \
- mono_threads_finish_blocking (__blocking_cookie, &__dummy); \
- } while (0)
-
-#define MONO_PREPARE_RESET_BLOCKING \
- do { \
- gpointer __dummy; \
- gpointer __reset_cookie = mono_threads_reset_blocking_start (&__dummy)
-
-#define MONO_FINISH_RESET_BLOCKING \
- mono_threads_reset_blocking_end (__reset_cookie, &__dummy); \
- } while (0)
-
/*
* The following are used for wrappers and trampolines as their
* calls might be unbalanced, due to exception unwinding.
*/
gpointer
-mono_threads_prepare_blocking_unbalanced (gpointer *stackdata);
+mono_threads_enter_gc_safe_region_unbalanced (gpointer *stackdata);
void
-mono_threads_finish_blocking_unbalanced (gpointer cookie, gpointer *stackdata);
+mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata);
gpointer
-mono_threads_reset_blocking_start_unbalanced (gpointer *stackdata);
+mono_threads_enter_gc_unsafe_region_unbalanced (gpointer *stackdata);
void
-mono_threads_reset_blocking_end_unbalanced (gpointer cookie, gpointer *stackdata);
+mono_threads_exit_gc_unsafe_region_unbalanced (gpointer cookie, gpointer *stackdata);
-#define MONO_PREPARE_RESET_BLOCKING_UNBALANCED \
+#define MONO_ENTER_GC_UNSAFE_UNBALANCED \
do { \
gpointer __dummy; \
- gpointer __reset_cookie = mono_threads_reset_blocking_start_unbalanced (&__dummy)
+ gpointer __reset_cookie = mono_threads_enter_gc_unsafe_region_unbalanced (&__dummy)
-#define MONO_FINISH_RESET_BLOCKING_UNBALANCED \
- mono_threads_reset_blocking_end_unbalanced (__reset_cookie, &__dummy); \
+#define MONO_EXIT_GC_UNSAFE_UNBALANCED \
+ mono_threads_exit_gc_unsafe_region_unbalanced (__reset_cookie, &__dummy); \
} while (0)
G_END_DECLS
if (alerted)
return sleep_interruptable (ms, alerted);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
if (ms == INFINITE) {
do {
#endif /* __linux__ */
}
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return 0;
}
gint
mono_thread_info_usleep (guint64 us)
{
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
g_usleep (us);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
return 0;
}
MonoThreadUnwindState* mono_thread_info_get_suspend_state (THREAD_INFO_TYPE *info);
gpointer
-mono_threads_cookie_for_reset_blocking_start (THREAD_INFO_TYPE *info);
+mono_threads_enter_gc_unsafe_region_cookie (THREAD_INFO_TYPE *info);
void mono_thread_info_wait_for_resume (THREAD_INFO_TYPE *info);
#endif
sprintf (service_name, "%d", port);
- MONO_PREPARE_BLOCKING;
+ MONO_ENTER_GC_SAFE;
ret = getaddrinfo (hostname, service_name, &hints, &info);
- MONO_FINISH_BLOCKING;
+ MONO_EXIT_GC_SAFE;
if (ret)
return 1; /* FIXME propagate the error */