Skip to content

Instantly share code, notes, and snippets.

@lambdageek
Created January 29, 2020 21:54
Show Gist options
  • Save lambdageek/36165083afd1b7d2299b3fd08f0fd5cf to your computer and use it in GitHub Desktop.
Save lambdageek/36165083afd1b7d2299b3fd08f0fd5cf to your computer and use it in GitHub Desktop.
native thread prevents runtime shutdown
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
typedef void (*FnPtr) (void);
static pthread_mutex_t mut;
static pthread_cond_t cnd;
static FnPtr d;
static void*
native_starter (void *arg);
void FooStart (FnPtr p) {
pthread_mutex_init (&mut, (void*)0);
pthread_cond_init (&cnd, (void*)0);
d = p;
printf ("FooStart: starting native thread\n");
pthread_mutex_lock (&mut);
pthread_t t;
pthread_create (&t, (void*)0, native_starter, (void*)0);
pthread_detach (t);
pthread_cond_wait (&cnd, &mut);
pthread_mutex_unlock (&mut);
printf ("FooStart: native thread signaled us, returning to managed\n");
pthread_cond_destroy (&cnd);
pthread_mutex_destroy (&mut);
}
static void*
native_starter (void *arg)
{
pthread_mutex_lock (&mut);
printf ("native thread: calling managed\n");
d ();
printf ("native thread: returned from managed\n");
pthread_cond_signal (&cnd);
pthread_mutex_unlock (&mut);
//for (int i = 0; i < 2; ++i) {
while (1) {
printf ("native thread: sleeping\n");
sleep (1);
}
return (void*)0;
}
SOEXT:=dylib
#SOEXT:=so
all: Prog.exe libFoo.$(SOEXT)
.PHONY: all clean
Prog.exe: Prog.cs
csc $<
libFoo.$(SOEXT): foo.c
$(CC) -o $@ -shared -g $<
clean:
-rm -f Prog.exe
-rm -f libFoo.$(SOEXT)
-rm -rf libFoo.dylib.dSYM/
using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
delegate void MyDelegate ();
public class Prog {
[DllImport("Foo", EntryPoint="FooStart")]
extern static void FooStart (MyDelegate d);
public static void Main () {
var d = new MyDelegate (SomeMethod);
d ();
FooStart (d);
// var w = new Thread (() => { d (); });
//w.Start ();
// w.Join ();
return;
// Expected result:
// we return here
// Actual result:
// we hang waiting for the native thread
}
public static void SomeMethod () {
var t = Thread.CurrentThread;
Console.WriteLine ("Called from: {0} ({1})", t.ManagedThreadId,
t.IsBackground ? "Background" : "Not Background");
}
}
@lambdageek
Copy link
Author

I tried Mono versions between 6.11 and 4.2.4 on OSX and Linux and the program always hangs.
As far as I can tell this never worked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment