Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q. about calling wrapped functions from threads / dispatch queues #18

Open
Numpsy opened this issue Aug 24, 2017 · 6 comments
Open

Q. about calling wrapped functions from threads / dispatch queues #18

Numpsy opened this issue Aug 24, 2017 · 6 comments

Comments

@Numpsy
Copy link
Contributor

Numpsy commented Aug 24, 2017

Hi,
Another question about a possible issue i'm seeing:

I'm just trying to create a native (ObjC/C) wrapper for a new lib, and do ports of the Windows tests at the same time. Some of those tests involve trying things from multiple threads.

I'm calling attachCurrentThread for each new thread before doing any work with the managed side, and that seems to be working ok, however I then get a hang in the native cleanup side, which seems to be down to

- (void)dealloc
{
    // Mono requires mono_thread_attach() to be called before accessing the runtime from a thread.
    // We could do this but it seems prudent just to dispatch the required operation onto the main thread.
        
    // hmm. need to be careful here that we don't inadvertently make an inappropriate call during the dealloc.
   [self performSelectorOnMainThread:@selector(disposeOfInstance) withObject:nil waitUntilDone:YES];
}

in DBManagedObject, where performSelectorOnMainThread hits a lock and never comes back. Not sure if this is a supported scenario, but there it is?

fwiw I tried to have a look at how embeddinator-4000 handles this situation and they seem to have worked around it by adding calls to mono_threads_attach_coop/mono_threads_detach_coop around every wrapped function, though interestingly they don't seem to do it for the dealloc/mono_gchandle_free calls (not sure if mono_gchandle_free has different requirements than the other mono_functions?)

@Thesaurus
Copy link
Contributor

Thesaurus commented Aug 24, 2017 via email

@Numpsy
Copy link
Contributor Author

Numpsy commented Aug 24, 2017

looks like it hits _pthread_cond_wait inside performSelectorOnMainThread, and that's it. Possibly just because the main thread is waiting for the tests to complete, so it can't be switched to? (my knowledge of threading stuff on OSX is pretty basic, but i do see the docs making special mention of issues with performSelectorOnMainThread together with dispatch queues?)

Embeddinator-4000 is a more basic/low-level project than Dubrovnik (e.g. doesn't support runtime features like delegates and events, or i think the extra runtime subclass handling etc), but it is being run by the Mono/Xamarin guys, so more knowledge of the inners of Mono and such I suppose.

@Thesaurus
Copy link
Contributor

Thesaurus commented Aug 24, 2017 via email

@Numpsy
Copy link
Contributor Author

Numpsy commented Aug 24, 2017

What happens if you use waitUntilDone NO?

I'll have a look tommorow. (might make it try to read class members after it's been dealloced?)

Personally I am still pretty amazed that whole Dubrovnik project works at all.

Outside the few issues i've raised, it's been working fine great for us (no shortage of other things that cause more issues in the project!)

@Numpsy
Copy link
Contributor Author

Numpsy commented Aug 25, 2017

nope, waitUntilDone:NO just makes it crash on throw (calling disploseOfInstance on the wrong object)

@Numpsy
Copy link
Contributor Author

Numpsy commented Aug 25, 2017

fwiw, I asked about the threading situation with mono_gc_handle_free on the embeddinator gitter, and got the reply "the GCHandle API does not require mono to know about the thread".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants