[Ocfs2-tools-commits] manish commits r634 - trunk/ocfs2console/ocfs2interface

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Feb 17 21:43:55 CST 2005


Author: manish
Date: 2005-02-17 21:43:53 -0600 (Thu, 17 Feb 2005)
New Revision: 634

Modified:
   trunk/ocfs2console/ocfs2interface/format.py
   trunk/ocfs2console/ocfs2interface/main.py
   trunk/ocfs2console/ocfs2interface/ocfs2module.c
   trunk/ocfs2console/ocfs2interface/ocfsplist.c
   trunk/ocfs2console/ocfs2interface/ocfsplist.h
Log:
Asynchronous partition list loading


Modified: trunk/ocfs2console/ocfs2interface/format.py
===================================================================
--- trunk/ocfs2console/ocfs2interface/format.py	2005-02-10 21:28:09 UTC (rev 633)
+++ trunk/ocfs2console/ocfs2interface/format.py	2005-02-18 03:43:53 UTC (rev 634)
@@ -144,8 +144,13 @@
 )
 
 def format_partition(parent, device):
-    partitions = ocfs2.partition_list(unmounted=True)
+    partitions = []
 
+    def add_partition(device):
+        partitions.append(device)
+
+    ocfs2.partition_list(add_partition, unmounted=True)
+
     if not partitions:
         error_box(parent, 'No unmounted partitions')
         return False

Modified: trunk/ocfs2console/ocfs2interface/main.py
===================================================================
--- trunk/ocfs2console/ocfs2interface/main.py	2005-02-10 21:28:09 UTC (rev 633)
+++ trunk/ocfs2console/ocfs2interface/main.py	2005-02-18 03:43:53 UTC (rev 634)
@@ -79,6 +79,8 @@
             return None
 
     def on_select(self, sel):
+        self.selected = True
+
         device, mountpoint = self.get_sel_values()
 
         if mountpoint:
@@ -118,22 +120,26 @@
         store = gtk.ListStore(str, str)
         self.set_model(store)
 
-        sel = self.get_selection()
-        selected = False
+        self.store = store
+        self.sel = self.get_selection()
+        self.selected = False
 
-        for partition in ocfs2.partition_list(filter=filter):
-            iter = store.append(partition)
-
-            if partition[0] == old_device:
-                sel.select_iter(iter)
-                selected = True
-
         store.set_sort_func(COLUMN_DEVICE, list_compare)
         store.set_sort_column_id(COLUMN_DEVICE, gtk.SORT_ASCENDING)
 
-        if len(store) and not selected:
-            sel.select_iter(store.get_iter_first())
+        ocfs2.partition_list(self.add_partition, data=old_device,
+                             filter=filter, async=True)
 
+        if len(store) and not self.selected:
+            self.sel.select_iter(store.get_iter_first())
+
+    def add_partition(self, device, mountpoint, old_device):
+        iter = self.store.append((device, mountpoint))
+
+        if device == old_device:
+            self.sel.select_iter(iter)
+            self.selected = True
+
 def mount(pv):
     device, mountpoint = pv.get_sel_values()
 

Modified: trunk/ocfs2console/ocfs2interface/ocfs2module.c
===================================================================
--- trunk/ocfs2console/ocfs2interface/ocfs2module.c	2005-02-10 21:28:09 UTC (rev 633)
+++ trunk/ocfs2console/ocfs2interface/ocfs2module.c	2005-02-18 03:43:53 UTC (rev 634)
@@ -39,74 +39,102 @@
 
 static PyObject *ocfs2_error;
 
+typedef struct
+{
+  PyObject *func;
+  PyObject *data;
+} ProxyData;
+
+static void
+proxy_partition_func (OcfsPartitionInfo *info,
+		      gpointer           pdata)
+{
+  ProxyData *data = pdata;
+
+  PyObject_CallFunction (data->func, "ss", info->device, info->mountpoint);
+}
+
+static void
+proxy_partition_func_data (OcfsPartitionInfo *info,
+			   gpointer           pdata)
+{
+  ProxyData *data = pdata;
+
+  PyObject_CallFunction (data->func, "ssO",
+			 info->device, info->mountpoint, data->data);
+}
+
+static void
+proxy_unmounted_func (OcfsPartitionInfo *info,
+		      gpointer           pdata)
+{
+  ProxyData *data = pdata;
+
+  PyObject_CallFunction (data->func, "s", info->device);
+}
+
+static void
+proxy_unmounted_func_data (OcfsPartitionInfo *info,
+			   gpointer           pdata)
+{
+  ProxyData *data = pdata;
+
+  PyObject_CallFunction (data->func, "sO", info->device, data->data);
+}
+
+
 static PyObject *
 partition_list (PyObject *self,
 		PyObject *args,
 		PyObject *kwargs)
 {
-  gchar             *filter = NULL;
-  gboolean           unmounted = FALSE, bail = FALSE;
-  GList             *list, *last;
-  PyObject          *ret, *val;
-  OcfsPartitionInfo *info;
+  ProxyData              proxy_data;
+  OcfsPartitionListFunc  func;
+  PyObject              *py_func, *py_data = NULL;
+  gchar                 *filter = NULL;
+  gboolean               unmounted = FALSE, async = FALSE;
 
-  static gchar *kwlist[] = { "filter", "unmounted", NULL };
+  static gchar *kwlist[] = {
+    "callback", "data",
+    "filter", "unmounted", "async",
+    NULL
+  };
 
   if (!PyArg_ParseTupleAndKeywords (args, kwargs,
-				    "|si:partition_list", kwlist,
-				    &filter, &unmounted))
+				    "O|Osii:partition_list", kwlist,
+				    &py_func, &py_data,
+				    &filter, &unmounted, &async))
     return NULL;
 
-  list = ocfs_partition_list (filter, unmounted);
+  if (!PyCallable_Check (py_func))
+    {
+      PyErr_SetString (PyExc_TypeError, "callback must be a callable object");
+      return NULL;
+    }
 
-  ret = PyList_New (0);
-  if (ret == NULL)
-    bail = TRUE;
+  proxy_data.func = py_func;
 
-  while (list)
+  if (py_data)
     {
+      proxy_data.data = py_data;
 
-      if (!bail)
-	{
-	  if (!unmounted)
-	    {
-	      info = list->data;
-	      val = Py_BuildValue ("(ss)", info->device, info->mountpoint);
-	    }
-	  else
-	    val = PyString_FromString (list->data);
-
-	  if (val)
-	    {
-	      PyList_Append (ret, val);
-	      Py_DECREF (val);
-	    }
-	  else
-	    bail = TRUE;
-	}
-
-      if (!unmounted)
-	{
-	  g_free (info->device);
-	  g_free (info->mountpoint);
-	  g_free (info);
-        }
+      if (unmounted)
+	func = proxy_unmounted_func_data;
       else
-	g_free (list->data);
-
-      last = list;
-      list = list->next;
-
-      g_list_free_1 (last);
+	func = proxy_partition_func_data;
     }
-
-  if (bail)
+  else
     {
-      Py_XDECREF (ret);
-      return NULL;
+      if (unmounted)
+	func = proxy_unmounted_func;
+      else
+	func = proxy_partition_func;
     }
-  else
-    return ret;
+
+  ocfs_partition_list (func, &proxy_data, filter, unmounted, async);
+
+  Py_INCREF (Py_None);
+  return Py_None;
 }
 
 static PyStructSequence_Field struct_ocfs2_super_fields[] = {

Modified: trunk/ocfs2console/ocfs2interface/ocfsplist.c
===================================================================
--- trunk/ocfs2console/ocfs2interface/ocfsplist.c	2005-02-10 21:28:09 UTC (rev 633)
+++ trunk/ocfs2console/ocfs2interface/ocfsplist.c	2005-02-18 03:43:53 UTC (rev 634)
@@ -39,14 +39,22 @@
 #include "ocfsplist.h"
 
 
-typedef struct _BuildData BuildData;
+#define FILL_ASYNC_ITERATIONS 20
+#define WALK_ASYNC_ITERATIONS 10
 
-struct _BuildData
+
+typedef struct _WalkData WalkData;
+
+struct _WalkData
 {
-  GPatternSpec *filter;
-  gboolean      unmounted;
+  OcfsPartitionListFunc  func;
+  gpointer               data;
 
-  GList        *list;
+  GPatternSpec          *filter;
+  gboolean               unmounted;
+  gboolean               async;
+
+  guint                  count;
 };
 
 
@@ -54,12 +62,27 @@
 static gboolean valid_device        (const gchar  *device,
 				     GPatternSpec *filter,
 				     gboolean      no_ocfs_check);
-static void     partition_info_fill (GHashTable   *info);
-static gboolean list_builder        (gpointer      key,
+static void     partition_info_fill (GHashTable   *info,
+                                     gboolean      async);
+static gboolean partition_walk      (gpointer      key,
 				     gpointer      value,
 				     gpointer      user_data);
 
 
+static inline void
+async_loop_run (gboolean     async,
+		guint       *count,
+                const guint  num_iterations)
+{
+  if (async)
+    {
+      *count++;
+
+      if (*count % num_iterations == 0)
+	while (g_main_context_iteration(NULL, FALSE));
+    }
+}
+
 static gboolean
 is_ocfs2_partition (const gchar *device)
 {
@@ -132,13 +155,15 @@
 }
 
 static void
-partition_info_fill (GHashTable *info)
+partition_info_fill (GHashTable *info,
+		     gboolean    async)
 {
   FILE   *proc;
   gchar   line[100], name[100], *device;
   GSList *list;
   gint    i;
   gchar  *p;
+  guint   count = 0;
 
   proc = fopen ("/proc/partitions", "r");
   if (proc == NULL)
@@ -185,63 +210,51 @@
 	}
       else
 	g_free (device);
+
+      async_loop_run (async, &count, FILL_ASYNC_ITERATIONS);
     }
 
   fclose (proc);
 }
 
 static gboolean
-list_builder (gpointer key,
-	      gpointer value,
-	      gpointer user_data)
+partition_walk (gpointer key,
+		gpointer value,
+		gpointer user_data)
 {
-  BuildData         *bdata;
+  WalkData          *wdata;
   GSList            *list, *last;
   gchar             *device;
   gchar              mountpoint[PATH_MAX];
-  OcfsPartitionInfo *info;
+  OcfsPartitionInfo  info;
   gint               flags;
   errcode_t          ret;
 
-  bdata = user_data;
+  wdata = user_data;
   list = value;
 
   while (list)
     {
       device = list->data;
 
-      if (valid_device (device, bdata->filter, bdata->unmounted))
+      if (valid_device (device, wdata->filter, wdata->unmounted))
 	{
-	  info = g_new (OcfsPartitionInfo, 1);
+	  info.device = device;
 
-	  info->device = g_strdup (device);
-
 	  ret = ocfs2_check_mount_point (device, &flags, mountpoint, PATH_MAX);
 
 	  if (ret == 0)
 	    {
 	      if (flags & OCFS2_MF_MOUNTED)
-		info->mountpoint = g_strdup (mountpoint);
+		info.mountpoint = mountpoint;
 	      else
-		info->mountpoint = NULL;
+		info.mountpoint = NULL;
 	    }
 	  else
-	    info->mountpoint = NULL;
+	    info.mountpoint = NULL;
 
-	  if (bdata->unmounted)
-	    {
-	      if (info->mountpoint)
-		{
-		  g_free (info->mountpoint);
-		  g_free (info->device);
-		}
-	      else
-		bdata->list = g_list_prepend (bdata->list, info->device);
-
-	      g_free (info);
-	    }
-	  else
-	    bdata->list = g_list_prepend (bdata->list, info);
+	  if (!wdata->unmounted || !info.mountpoint)
+	    wdata->func (&info, wdata->data);
 	}
 
       last = list;
@@ -249,6 +262,8 @@
 
       g_free (device);
       g_slist_free_1 (last);
+
+      async_loop_run (wdata->async, &wdata->count, WALK_ASYNC_ITERATIONS);
     }
 
   g_free (key);
@@ -271,32 +286,41 @@
 }
 #endif
 
-GList *
-ocfs_partition_list (const gchar *filter,
-                     gboolean     unmounted)
+void
+ocfs_partition_list (OcfsPartitionListFunc  func,
+		     gpointer               data,
+		     const gchar           *filter,
+		     gboolean               unmounted,
+		     gboolean               async)
 {
   GHashTable *info;
-  BuildData   bdata = { NULL, unmounted, NULL };
+  WalkData    wdata = { func, data, NULL, unmounted, async, 0 };
 
   if (filter && *filter)
-    bdata.filter = g_pattern_spec_new (filter);
+    wdata.filter = g_pattern_spec_new (filter);
 
   info = g_hash_table_new (g_str_hash, g_str_equal);
 
-  partition_info_fill (info);
+  partition_info_fill (info, async);
 
 #ifdef LIST_TEST_HASH
   g_hash_table_foreach (info, print_hash, NULL);
 #endif
 
-  g_hash_table_foreach_remove (info, list_builder, &bdata);
+  g_hash_table_foreach_remove (info, partition_walk, &wdata);
   
   g_hash_table_destroy (info);
+}
 
-  return bdata.list;
+#ifdef LIST_TEST
+static void
+list_func (OcfsPartitionInfo *info,
+           gpointer           data)
+{
+  g_print ("Device: %s; Mountpoint %s\n",
+           info->device, info->mountpoint ? info->mountpoint : "N/A");
 }
 
-#ifdef LIST_TEST
 int
 main (int    argc,
       char **argv)
@@ -305,22 +329,11 @@
   OcfsPartitionInfo *info;
 
   g_print ("All:\n");
-
-  plist = ocfs_partition_list (NULL, FALSE);
+  ocfs_partition_list (list_func, NULL, FALSE);
   
-  for (list = plist; list; list = list->next)
-    {
-      info = list->data;
-      g_print ("Device: %s; Mountpoint %s\n", info->device, info->mountpoint);
-    }
-
   g_print ("Unmounted:\n");
+  plist = ocfs_partition_list (list_func, NULL, TRUE);
 
-  plist = ocfs_partition_list (TRUE);
-  
-  for (list = plist; list; list = list->next)
-    g_print ("Device: %s\n", (gchar *) list->data);
-
   return 0;
 }
 #endif

Modified: trunk/ocfs2console/ocfs2interface/ocfsplist.h
===================================================================
--- trunk/ocfs2console/ocfs2interface/ocfsplist.h	2005-02-10 21:28:09 UTC (rev 633)
+++ trunk/ocfs2console/ocfs2interface/ocfsplist.h	2005-02-18 03:43:53 UTC (rev 634)
@@ -38,8 +38,15 @@
 };
 
 
-GList *ocfs_partition_list (const gchar *filter,
-                            gboolean     unmounted);
+typedef void (*OcfsPartitionListFunc) (OcfsPartitionInfo *info,
+				       gpointer           data);
 
 
+void ocfs_partition_list (OcfsPartitionListFunc  func,
+			  gpointer               data,
+			  const gchar           *filter,
+			  gboolean               unmounted,
+			  gboolean               async);
+
+
 #endif /* __OCFS_PARTITION_LIST_H__ */



More information about the Ocfs2-tools-commits mailing list