aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael 'Mickey' Lauer <mickey@vanille-media.de>2009-05-08 22:48:50 +0200
committerMichael 'Mickey' Lauer <mickey@vanille-media.de>2009-05-08 22:48:50 +0200
commit5f3d4a73f2de884122a758fffb077dfe6ba76b0f (patch)
tree40ad633067da3656a723e6920a1759b885b9cfb6
parent69d6bc60f622309bfdbc46b54beea2c9945ba45b (diff)
downloadcornucopia-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.vapi9
-rw-r--r--libfsoframework/fsoframework/kobjectnotifier.vala136
-rw-r--r--libfsoframework/tests/testkobjectnotifier.vala9
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();