diff options
author | Michael 'Mickey' Lauer <mickey@vanille-media.de> | 2009-05-08 22:48:50 +0200 |
---|---|---|
committer | Michael 'Mickey' Lauer <mickey@vanille-media.de> | 2009-05-08 22:48:50 +0200 |
commit | 5f3d4a73f2de884122a758fffb077dfe6ba76b0f (patch) | |
tree | 40ad633067da3656a723e6920a1759b885b9cfb6 | |
parent | 69d6bc60f622309bfdbc46b54beea2c9945ba45b (diff) | |
download | cornucopia-5f3d4a73f2de884122a758fffb077dfe6ba76b0f.tar.gz cornucopia-5f3d4a73f2de884122a758fffb077dfe6ba76b0f.tar.bz2 cornucopia-5f3d4a73f2de884122a758fffb077dfe6ba76b0f.zip |
fsoframework: first version of kobjectnotifier now works
-rw-r--r-- | libfsoframework/fsoframework/fsoframework-2.0.vapi | 9 | ||||
-rw-r--r-- | libfsoframework/fsoframework/kobjectnotifier.vala | 136 | ||||
-rw-r--r-- | libfsoframework/tests/testkobjectnotifier.vala | 9 |
3 files changed, 136 insertions, 18 deletions
diff --git a/libfsoframework/fsoframework/fsoframework-2.0.vapi b/libfsoframework/fsoframework/fsoframework-2.0.vapi index 409fab92..16075d48 100644 --- a/libfsoframework/fsoframework/fsoframework-2.0.vapi +++ b/libfsoframework/fsoframework/fsoframework-2.0.vapi @@ -120,9 +120,12 @@ namespace FsoFramework { } [CCode (cheader_filename = "fsoframework.h")] public class BaseKObjectNotifier : GLib.Object { - public void addMatch (); + public static FsoFramework.BaseKObjectNotifier instance; + protected void _addMatch (string action, string subsystem, FsoFramework.KObjectNotifierFunc callback); + public static void addMatch (string action, string path, FsoFramework.KObjectNotifierFunc callback); + public void handleMessage (string[] parts); public BaseKObjectNotifier (); - public bool onActionFromSocket (GLib.IOChannel source, GLib.IOCondition condition); + protected bool onActionFromSocket (GLib.IOChannel source, GLib.IOCondition condition); } [CCode (cheader_filename = "fsoframework.h")] public class BasePlugin : FsoFramework.Plugin, GLib.TypeModule { @@ -225,6 +228,8 @@ namespace FsoFramework { } [CCode (cheader_filename = "fsoframework.h", has_target = false)] public delegate string FactoryFunc (FsoFramework.Subsystem subsystem); + [CCode (cheader_filename = "fsoframework.h")] + public delegate void KObjectNotifierFunc (GLib.HashTable<string,string> properties); [CCode (cheader_filename = "fsoframework.h", has_target = false)] public delegate void RegisterFunc (GLib.TypeModule bar); [CCode (cheader_filename = "fsoframework.h")] diff --git a/libfsoframework/fsoframework/kobjectnotifier.vala b/libfsoframework/fsoframework/kobjectnotifier.vala index cee08a02..a78f471a 100644 --- a/libfsoframework/fsoframework/kobjectnotifier.vala +++ b/libfsoframework/fsoframework/kobjectnotifier.vala @@ -19,11 +19,25 @@ using GLib; +public delegate void FsoFramework.KObjectNotifierFunc( HashTable<string, string> properties ); + +[Compact] +internal class DelegateHolder +{ + public FsoFramework.KObjectNotifierFunc func; + DelegateHolder( FsoFramework.KObjectNotifierFunc func ) + { + this.func = func; + } +} + /** * @class FsoFramework.BaseKObjectNotifier **/ public class FsoFramework.BaseKObjectNotifier : Object { + public static BaseKObjectNotifier instance; + private int fd = -1; private uint watch; private IOChannel channel; @@ -32,32 +46,40 @@ public class FsoFramework.BaseKObjectNotifier : Object private const ssize_t BUFFER_LENGTH = 4096; + private HashTable<string, List<DelegateHolder>> add; + private HashTable<string, List<DelegateHolder>> change; + private HashTable<string, List<DelegateHolder>> remove; + public BaseKObjectNotifier() { buffer = new char[BUFFER_LENGTH]; + add = new HashTable<string, List<DelegateHolder>>( str_hash, str_equal ); + change = new HashTable<string, List<DelegateHolder>>( str_hash, str_equal ); + remove = new HashTable<string, List<DelegateHolder>>( str_hash, str_equal ); + fd = Posix.socket( Linux26.Netlink.AF_NETLINK, Posix.SOCK_DGRAM, Linux26.Netlink.NETLINK_KOBJECT_UEVENT ); assert( fd != -1 ); - Linux26.Netlink.SockAddrNl addr = { Linux26.Netlink.AF_NETLINK, - 0, - PosixExtra.getpid(), - 1 }; + Linux26.Netlink.SockAddrNl addr = { Linux26.Netlink.AF_NETLINK, 0, PosixExtra.getpid(), 1 }; var res = PosixExtra.bind( fd, &addr, sizeof( Linux26.Netlink.SockAddrNl ) ); assert( res != -1 ); channel = new IOChannel.unix_new( fd ); watch = channel.add_watch( IOCondition.IN | IOCondition.HUP, onActionFromSocket ); - } - public void addMatch() + ~BaseKObjectNotifier() { - message( "yo" ); + if ( watch != 0 ) + Source.remove( watch ); + + if ( fd != -1 ) + Posix.close( fd ); } - public bool onActionFromSocket( IOChannel source, IOCondition condition ) + protected bool onActionFromSocket( IOChannel source, IOCondition condition ) { if ( ( condition & IOCondition.HUP ) == IOCondition.HUP ) { @@ -70,13 +92,107 @@ public class FsoFramework.BaseKObjectNotifier : Object assert( fd != -1 ); assert( buffer != null ); ssize_t bytesread = Posix.read( fd, buffer, BUFFER_LENGTH ); + for( int i = 0; i < bytesread-1; ++i ) + if ( buffer[i] == 0x00 ) + buffer[i] = 0x09; + + var parts = ( (string)buffer ).split( "\t" ); - message( "got message from socket: %s", (string)buffer ); + handleMessage( parts ); return true; } - assert_not_reached(); + assert_not_reached(); // fail on unexpected IOCondition + } + + protected void handleMessage( string[] parts ) + { + var properties = new HashTable<string, string>( str_hash, str_equal ); + foreach ( var part in parts ) + { + var elements = part.split( "=" ); + if ( elements.length == 2 ) + { + properties.insert( elements[0], elements[1] ); + } + } + + var action = properties.lookup( "ACTION" ); + assert( action != null ); + var subsystem = properties.lookup( "SUBSYSTEM" ); + assert( subsystem != null ); + + message( "dealing with action '%s' for subsystem '%s'", action, subsystem ); + + HashTable<string, List<DelegateHolder>> table; + + switch( action ) + { + case "add": + table = add; + break; + case "change": + table = change; + break; + case "remove": + table = remove; + break; + default: + assert_not_reached(); + } + + weak List<weak DelegateHolder> list = table.lookup( subsystem ); + if ( list == null ) + return; + + foreach( var delegateholder in list ) + delegateholder.func( properties ); + } + + protected void _addMatch( string action, string subsystem, KObjectNotifierFunc callback ) + { + HashTable<string, List<DelegateHolder>> table; + + switch( action ) + { + case "add": + table = add; + break; + case "change": + table = change; + break; + case "remove": + table = remove; + break; + default: + assert_not_reached(); + } + + weak List<DelegateHolder> list = table.lookup( subsystem ); + if ( list == null ) + { + List<DelegateHolder> newlist = new List<DelegateHolder>(); + newlist.append( new DelegateHolder( callback ) ); + message( "# delegates for action '%s' and subsystem '%s' now %u", action, subsystem, newlist.length() ); + table.insert( subsystem, (owned) newlist ); + } + else + { + list.append( new DelegateHolder( callback ) ); + message( "# delegates for action '%s' and subsystem '%s' now %u", action, subsystem, list.length() ); + } + } + + // + // public API + // + public static void addMatch( string action, string path, KObjectNotifierFunc callback ) + { + if ( BaseKObjectNotifier.instance == null ) + BaseKObjectNotifier.instance = new BaseKObjectNotifier(); + + BaseKObjectNotifier.instance._addMatch( action, path, callback ); } } diff --git a/libfsoframework/tests/testkobjectnotifier.vala b/libfsoframework/tests/testkobjectnotifier.vala index 675a9d4e..aca1b7aa 100644 --- a/libfsoframework/tests/testkobjectnotifier.vala +++ b/libfsoframework/tests/testkobjectnotifier.vala @@ -20,18 +20,16 @@ using GLib; using FsoFramework; -//=========================================================================== -void test_kobjectnotifier_create() -//=========================================================================== +public void callback( HashTable<string, string> properties ) { - var kn = new BaseKObjectNotifier(); + debug( "got callback for subsystem '%s' with device path '%s'", properties.lookup( "SUBSYSTEM" ), properties.lookup( "DEVPATH" ) ); } //=========================================================================== void test_kobjectnotifier_add_match() //=========================================================================== { - var kn = new BaseKObjectNotifier(); + BaseKObjectNotifier.addMatch( "remove", "usb", callback ); ( new MainLoop( null, false ) ).run(); } @@ -42,7 +40,6 @@ void main( string[] args ) { Test.init( ref args ); - //Test.add_func( "/KObjectNotifier/Create", test_kobjectnotifier_create ); Test.add_func( "/KObjectNotifier/AddMatch", test_kobjectnotifier_add_match ); Test.run(); |