From c470a00e4d04a997c5fbbc8e719f237961e7bf44 Mon Sep 17 00:00:00 2001
From: John Darrington <john@darrington.wattle.id.au>
Date: Thu, 26 Sep 2013 19:36:11 +0200
Subject: [PATCH] Experimental patch to demonstrate concurrency.

This patch provides concurrency for the DESCRIPTIVES command.  No protection agains
reentrancy or other such issues is provided.  Not for general use.
---
 src/data/casereader.h             |    5 +++++
 src/language/stats/descriptives.c |    5 +++++
 src/ui/gui/executor.c             |   26 ++++++++++++++++++++++++++
 src/ui/terminal/main.c            |   11 +++++++++++
 4 files changed, 47 insertions(+)

diff --git a/src/data/casereader.h b/src/data/casereader.h
index 45ea2c1..acb76e1 100644
--- a/src/data/casereader.h
+++ b/src/data/casereader.h
@@ -165,4 +165,9 @@ casereader_create_distinct (struct casereader *input,
 			    const struct variable *weight);
 
 
+struct y
+{
+  casenumber cn;
+};
+
 #endif /* data/casereader.h */
diff --git a/src/language/stats/descriptives.c b/src/language/stats/descriptives.c
index 413826c..7d64f9f 100644
--- a/src/language/stats/descriptives.c
+++ b/src/language/stats/descriptives.c
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <glib.h>
 #include <limits.h>
 #include <math.h>
 #include <stdlib.h>
@@ -759,6 +760,7 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
   add_transformation (ds,
 		      descriptives_trns_proc, descriptives_trns_free, t);
 }
+
 
 /* Statistical calculation. */
 
@@ -775,6 +777,7 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
   struct ccase *c;
   size_t z_idx;
   size_t i;
+  struct y y={0};
 
   c = casereader_peek (group, 0);
   if (c == NULL)
@@ -810,6 +813,8 @@ calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
     {
       double weight = dict_get_case_weight (dataset_dict (ds), c, NULL);
 
+      yield (&y, pass1);
+
       /* Check for missing values. */
       if (listwise_missing (dsc, c))
         {
diff --git a/src/ui/gui/executor.c b/src/ui/gui/executor.c
index ee83c2c..a5376b4 100644
--- a/src/ui/gui/executor.c
+++ b/src/ui/gui/executor.c
@@ -18,6 +18,7 @@
 
 #include "ui/gui/executor.h"
 
+#include "data/casereader.h"
 #include "data/dataset.h"
 #include "data/lazy-casereader.h"
 #include "data/session.h"
@@ -83,6 +84,28 @@ new_pdw_cb (struct dataset *ds, void *aux UNUSED)
   dataset_set_display (ds, DATASET_ASIS);
 }
 
+PsppireDataWindow *executing_window;
+
+
+void
+yield (struct y *y, const struct casereader *r)
+{
+  gchar str[100];
+  if ((++y->cn % 100) == 0)
+    {
+      if (executing_window)
+	{
+	  GtkWidget *cca_label  =
+	    get_widget_assert (executing_window->builder, "case-counter-area");
+	  
+	  g_snprintf (str, 100, "Casenumber %lu", y->cn);
+	  gtk_label_set_label (cca_label, str);
+	}
+      g_main_context_iteration (g_main_context_default(), FALSE);
+    }
+}
+
+
 gboolean
 execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader)
 {
@@ -129,6 +152,7 @@ execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader)
   psppire_set_lexer (lexer);
   lex_append (lexer, lex_reader);
 
+  executing_window = window;
   for (;;)
     {
       struct dataset *ds = session_active_dataset (the_session);
@@ -145,6 +169,7 @@ execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader)
 	break;
     }
 
+
   session_for_each_dataset (the_session, name_dataset_cb, NULL);
 
   ll_for_each_safe (pdw, next_pdw, PsppireDataWindow, ll, &all_data_windows)
@@ -174,6 +199,7 @@ execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader)
     }
 
   session_for_each_dataset (the_session, new_pdw_cb, NULL);
+  executing_window = NULL;
 
   /* Destroy the lexer only after obtaining the dataset, because the dataset
      might depend on the lexer, if the casereader specifies inline data.  (In
diff --git a/src/ui/terminal/main.c b/src/ui/terminal/main.c
index c30b5f8..bfae513 100644
--- a/src/ui/terminal/main.c
+++ b/src/ui/terminal/main.c
@@ -243,3 +243,14 @@ add_syntax_reader (struct lexer *lexer, const char *file_name,
   if (reader)
     lex_append (lexer, reader);
 }
+
+
+struct y;
+struct casereader ;
+
+
+
+void
+yield (struct y *y, const struct casereader *r)
+{
+}
-- 
1.7.10.4

