[Mono-dev] Announce: Mono.Fuse (+ Required Mono.Posix Changes)
Jonathan Pryor
jonpryor at vt.edu
Wed Aug 30 21:51:34 EDT 2006
On Wed, 2006-08-30 at 18:07 +0200, Paolo Molaro wrote:
> > The biggest problem with the mono module is that no headers are
> > installed, making it difficult to make use of libMonoPosixHelper.so.
>
> This is for a good reason. libMonoPosixHelper.so is an internal
> implementation detail, it is not a good library to export for a million
> reasons and no header should be installed for it. It would be a
> compatibility nightmare.
I'm not entirely sure I see the "compatibility nightmare." Nor do I see
the "million reasons." The only reasons I can think of is that there
are some symbols which should be removed (e.g. the old Mono.Posix
namespace functions such as "wifexited" and "helper_Mono_Posix_Stat").
Regardless, here's the scenario I'm trying to solve: MonoFuseHelper is a
C library which has functions which register with FUSE. The
MonoFuseHelper functions invoke delegates registered by Mono.Fuse.dll,
e.g.
/* Within MonoFuseHelper */
static int
mfh_getattr (const char *path, struct stat *stat)
{
/* invoke delegate registered by Mono.Fuse.dll */
return _mfh_get_private_data()->getattr (path,
what_to_pass_here?);
}
The question is this: what should MonoFuseHelper pass to Mono.Fuse.dll?
There are two answers:
(1) Translate the native types into the managed types within
MonoFuseHelper, then invoke the Mono.Fuse.dll callback:
/* stat(2) */
static int
mfh_getattr (const char *path, struct stat *stat)
{
struct Mono_Posix_Stat _stat;
Mono_Posix_ToStat (stat, &_stat);
int r= _mfh_get_private_data()->getattr (path, &_stat);
Mono_Posix_FromErrno (r, &r);
return -r;
}
(The Errno translation & negation is because FUSE methods need to return
-errno on error.)
Pro:
- Requires fewer P/Invoke transitions, as all type conversions are
done in native code before invoking managed code (calling into
MonoPosixHelper).
- More efficient (due to above).
Con:
- Requires that MonoPosixHelper headers be installed so that the
Mono.Posix types & functions are accessible.
(2) Don't translate in native code, but just forward them to managed
code for translation within Mono.Fuse.dll:
/* stat(2) */
static int
mfh_getattr (const char *path, struct stat *stat)
{
return _mfh_get_private_data()->getattr (path, stat);
}
Managed code must then do everything:
private static int _OnGetFileAttributes (string path, IntPtr b)
{
Stat s;
NativeConvert.Copy (b, out s);
Errno e = OnGetFileAttributes (path, out s);
return - NativeConvert.FromErrno (e);
}
Pro:
- Doesn't require installing any headers for MonoPosixHelper.
Con:
- Requires more P/Invoke transitions.
- One P/Invoke transition to call NativeConvert.FromErrno
(done for each delegate invoked).
- One P/Invoke transition for each parameter that needs to
be converted (e.g. converting the IntPtr into a Stat, above).
- Requires adding several new methods to
Mono.Unix.Native.NativeConvert to copy structures between managed
and native (e.g. the NativeConvert.Copy() method used above).
I implemented solution (1) for efficiency reasons -- why invoke extra
P/Invoke calls when they can be avoided?
So I implemented (2) for comparison. The result: to copy a 100000000
byte file using `cat':
Average Copy Time
Solution 1: 4.8362s
Solution 2: 4.8613s
Since FUSE reads file contents in 4KB chunks, there is an average
overhead of .25us/call using (2).
So my efficiency concerns are likely overblown, and doing everything
from managed code will have acceptable performance.
> > mono-config.h is necessary because it needs to contain
> > platform-specific macros. In particular, Linux needs:
>
> Sorry, but there is no way to grab the mono-config.h name for this.
I'm sorry, but I don't understand this comment.
> > There are two major changes:
> >
> > * The addition of one public attributes to the API:
> \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\>
> > // targets Class, Delegate, Enum, Field, Struct
> > class Mono.Unix.Native.MapAttribute {
> > public MapAttribute ();
> > public MapAttribute (string nativeType);
> > public string NativeType {get;}
> > public string NativeSymbolPrefix {get; set;}
> > }
> >
> > * A major revamp to make-map.exe
>
> I don't think these changes are appropriate for mcs/. The Map attribute
> and make-map.exe are hacks that are tolerated only because they are used
> only internally. Exposing them for public use would only create
> comaptibility issues: they are not tools that can be maintained with the
> needed API and ABI stability required by a mono release.
I'm still not sure I see the compatibility issues.
Regardless, it sounds like you don't want MapAttribute to be a public
API in any way, and would prefer copy+pasting code between any projects
that want to make use of the make-map.exe mechanism.
I'm not entirely fond of extra copy+pasting if not necessary...
So a question/proposal: could we make make-map.exe/create-native-map
follow the "Applications Guidelines" for an unstable API to copy
create-native-map.exe itself and a .cs file for use within that
application?
Thus, instead of Mono.Posix.dll exporting a public attribute, we have an
easier way for people to make use of create-native-map without them
needing to copy the existing source code (they can instead copy an
existing binary & update as needed).
Thanks,
- Jon
More information about the Mono-devel-list
mailing list