[Mono-list] Calls to CIL code from native threads

Patrick Hartling patrick@vrac.iastate.edu
Tue, 27 Jan 2004 15:21:25 -0600


--=-w5i8cHrM7lu9y6Oj6aZt
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

On Tue, 2004-01-27 at 09:52, Paolo Molaro wrote:
> On 01/26/04 Patrick Hartling wrote:
> > I am working on a project that mixes CIL code with natively compiled C
> > and C++ in a multi-threaded environment.  The natively compiled code ma=
y
> > make calls into the CIL universe from different threads, and I am tryin=
g
> > to figure out how to manage that with Mono's C API.  In the
> > documentation about embedding Mono, I see a reference to the function
> > mono_thread_attach().  My (very preliminary) testing has allowed me to
> > make a call from a native thread other than the primordial thread into
> > the CIL universe by calling mono_thread_attach() first.  I pass in a
> > pointer to a MonoDomain object allocated on the heap by the calling
> > thread via mono_domain_create().
>=20
> Are you really using multiple domains in your app?

My understand of application domains is still very limited, so I am not
sure I can answer this question definitively.  If threads spawned by
native code each need their own domain, then yes, I am using multiple
domains.  Is there something different that I could call besides
mono_domain_create() to get a valid MonoDomain* to hand off to
mono_thread_attach()?

> If that's not the case you should pass the MonoDomain you get back from
> mono_jit_init().

I may not have described my situation in enough detail.  I have a C#
class with a static Main() function that I execute using Mono.  That
class instantiates an object that (conceptually) derives from a native
C++ object.  The C# object is handed off to C++ code where callbacks are
invoked from a thread spawned by the native code.  The end result is
that a C# object is handled polymorphically by C++ code.  The primary
thread of control in the C# Main() function blocks until the C++ code
shuts down.

At this point, I do not have code of my own that calls mono_jit_init().=20
In the long term, I probably will, but for now, I am concentrating on
making C# applications that can activate and utilize the native C++
libraries I am exposing for use with CLS-compliant languages.

> > After the call into the CIL code returns, however, I appear to get into
> > a deadlock state later when I make another call to
> > mono_thread_attach().  I have successfully dealt with a similar
>=20
> mono_thread_attach() should be called only once per-thread.
> If you're using multiple application domains, you may get all sort of
> issues, since the mono_thread_attach() implementation is broken in that
> case, there is already a bug filed about that.

I think that my analysis regarding a deadlock was wrong.  The
application was hanging, but I do not know where.  I modified things so
that mono_thread_attach() is called precisely once pre thread, and
things appear to be working quite well now.

> > situation using Python/C where the Global Interpreter Lock (GIL) must b=
e
> > acquired and released to allow native code threads to call into the
> > Python interpreter.  I am wondering if calling mono_thread_attach() has
> > the effect of acquiring a mutex somewhere that needs to be released by
> > my code when I no longer need to hold it.  Is that the case?  If so,
> > what is the call to make this happen?  Or am I just on the wrong track
> > entirely?
>=20
> If you're using multiple appdomains you're hitting a mono bug. If you're
> not, just try using mono_thread_attach() once per thread.
>=20
> > Lastly, is there any documentation for doing multi-threaded programming
> > with Mono?  So far, I have mostly been looking through the code trying
> > to find types and functions that look roughly like what I need.
>=20
> The API is supposed to be thread-safe, so there should be no particular
> thing to do apart from calling mono_thread_attach() in threads not
> created by mono. Please, see the suggestions above and report bavk if
> they solve your issue.
> Thanks.

Your suggestion of calling mono_thread_attach() once per thread appears
to have put things into good working order.  Thanks for the help.

 -Patrick


--=20
Patrick L. Hartling                     | Research Assistant, VRAC
patrick@vrac.iastate.edu                | 2274 Howe Hall Room 2624
http://www.vrac.iastate.edu/~patrick/   | http://www.vrac.iastate.edu/
PGP: http://wwwkeys.gpg.cz:11371/pks/lookup?op=3Dget&search=3D0xEBF86398


--=-w5i8cHrM7lu9y6Oj6aZt
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQBAFtZV5DgSg+v4Y5gRAsuMAJ4gJ89QCcZd1KgIlXWaqIjmJ7tNJwCdFRoS
+jA0MdvGdiFsKwufZSJrvZA=
=tEO/
-----END PGP SIGNATURE-----

--=-w5i8cHrM7lu9y6Oj6aZt--