On Wed, Sep 22, 2010 at 08:36:20AM +0200, Axel Simon wrote:
> Hi John,
> 
> same here: sorry for the delay.

no worries. I am not in a hurry and I can understand my questions
seem sometimes awkward.

> On Sep 13, 2010, at 2:40, John Obbele wrote:
> >Anyway, forget about this, I have kept things simple and only
> >coded a minimal subset of GHashTable, re-reading xfconf
> >documentation, it appears we only get (gchar*) keys and (gvalue*)
> >values.
> >
> >
> 
> Yes, that sounds better. If at all possible, you should not expose
> the user to GValues since these are too easy to get wrong (memory
> management, etc.). Please check what Duncan has done in gconf. I
> think he came up with a simple type class construction.

Oki, thanks for the advice.

I saw Duncan typeclass in GConf. I have not re-used it but I've
created a similar typeclass (in fact the idea comes also from
what I remember from RWH chapters about JSON).

On the subject about GValue, I'm getting a special behaviour,
don't know if it's can be called a bug and I've not yet test it
against recent 0.11 version:

So there is a C function with this signature:

"""
gboolean xfconf_channel_get_property(XfconfChannel *channel,
                                     const gchar *property,
                                     GValue *value);
"""

Which translates easily in haskell as:

"""
channelGetProperty :: XfconfChannelClass self
                   => self -> String -> IO (Maybe XfconfValue)
channelGetProperty chan property =
        withXfconf chan $ \chanPtr ->
        withUTFString property $ \prop ->
        allocaGValue $ \gvalue@(GValue gPtr) -> do
        -- c_get_property == FFI call to xfconf_channel_get_property
        success <- c_get_property chanPtr prop gPtr
        case fromGBoolean success of
          False -> do -- FIXME: bug in glib GValue implementation ?
                      -- gvalue was not initialize by c_get_property
                      -- allocaGValue will try to unset it
                      -- and throw an error if our gvalue stay as it is
                      valueInit gvalue bool
                      return Nothing
          True  -> Just `fmap` toXfconfValue gvalue
"""

As said in the haskell comment, when xfconf_channel_get_property
cannot find the property (the key in the xfconf "hash" table), it
returns False and doesn't set anything inside our GValue, which
trigger this glib error message:

"""
(process:20219): GLib-GObject-CRITICAL **: g_value_unset: assertion `G_IS_VALUE 
(value)' failed
"""

A simple work-around is to arbitrary valueInit'ed our gvalue to
something (bool in the previous code example) before ending our
haskell function (and letting allocaGValue clean the memory).

Note that if I valueInit' the gvalue before the call to xfconf, I
am getting an error saying Glib cannot initialized the gvalue
since it already was. (grrr)

... consequently, I propose to patch glib/System/Glib/GValue.chs
(or add a message in haddock warning against this edge case):

[!pseudo-patch attached!]

> >Then, concerning the question.  I would like to cast
> >XfconfChannel to a GObject, play with its attribute and connect
> >to it some signals.  If I've correctly understood the recent
> >cabalization of gtk2hs and its addons, and based on gconf-0.11, I
> >should hook Setup.hs to Gtk2HsSetup.hs, create two files,
> >"marshal.list" and "hierarchy.list" and modify the .cabal
> >configuration accordingly, am I right ?
> >
> 
> Yes. You need marshal.list if you have callbacks, otherwise you
> don't have to bother. You probably need hierarchy.list since that is
> required if you want the tools to create new class definitions.

I have successfully cast my object to the GObjectClass by copy-pasting
samples of code I have found. Same for signals, they are working
fine. ... except that I'm using plain vanilla c2hs with
pre-compiled gtk2hs-0.10 packages :(

I don't know if it really worths it now to try hooking my lib with
the Gtk2hsSetup.hs. Sorry but until I get a new fedora 14 system
(with shiny new gtk2hs-0.11 packages courtesy of J.Petersen), I
will stick with my simple hand-coded Signals.chs and Types.chs.

> >What if my reference to the XfconfChannel gobject is a "weak"
> >reference ? Is there some special things to do, since I do not
> >require a g_object_unref finalizer.
> 
> At the moment, a Haskell handle to an object is a strong reference.
> If it goes out of scope, then the reference counter of that object
> is decremented. This scheme is a bit problematic since you can
> create space leaks by creating closures that include these object
> references and then attach these closures to callbacks from the same
> object. We have not yet figured out a way to circumvent this
> problem. The only way to get rid of an object is to explicitly
> destroy it.

I have tried to solve my weak-reference problem by artificially
increasing the object reference with objectRef. If I've correctly
read the glib documentation, this should do the trick.

So everything could be fine if my quickcheck test suite was not
eating my RAM. `top` is saying that the quickcheck binary uses
14Mo for a 20*1000 samples testsuite against 22Mo for a 20*2000
samples testsuite.

On the other hand, GHC +RTS -sstderr keeps telling me that
garbage collection is ok and that everything is fine. But surely,
GHC does not count memory allocated through mallocBytes or {#call
g_malloc0 #}, does it ?

Perhaps I am just getting parano. +RTS -sstderr actually says,
for 20*1000 samples:

"""
  3,775,334,132 bytes allocated in the heap
     40,723,580 bytes copied during GC
        166,552 bytes maximum residency (30 sample(s))
        284,920 bytes maximum slop
              2 MB total memory in use (0 MB lost due to fragmentation)
"""

Should I understand that almost 3.78Go of test data where
mallocated and conclude that 14Mo of 'RES' RAM is small enough
for such a binary?

regards,
/John
--- glib/System/Glib/GValue.chs.old     2010-09-06 11:24:42.765482710 +0200
+++ glib/System/Glib/GValue.chs 2010-09-23 01:09:01.125703065 +0200
@@ -64,5 +64,9 @@
   -- The g_type field of the value must be zero or g_value_init will fail.
   {# set GValue->g_type #} gvPtr (0 :: GType)
   result <- body (GValue gvPtr)
-  {#call unsafe value_unset#} (GValue gvPtr)
+  -- Unset value if and only if it was initialized.
+  wasInitialised <- {#call unsafe g_type_check_value#} (GValue gvPtr)
+  if wasInitialised /= 0 -- True
+         then {#call unsafe value_unset#} (GValue gvPtr)
+         else return ()
   return result

Attachment: pgp0BC5UbBpu1.pgp
Description: PGP signature

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Gtk2hs-devel mailing list
Gtk2hs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel

Reply via email to