[gnumeric] solver: isolate OS differences in gnm-solver.c
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: isolate OS differences in gnm-solver.c
- Date: Tue, 17 Nov 2009 18:29:51 +0000 (UTC)
commit 379ca2bc31856e68bd5a729c0e0d4856d9cc639d
Author: Morten Welinder <terra gnome org>
Date: Tue Nov 17 13:29:25 2009 -0500
solver: isolate OS differences in gnm-solver.c
plugins/glpk/gnm-glpk.c | 20 ++++++------
plugins/lpsolve/gnm-lpsolve.c | 13 +++-----
src/gnm-marshalers.list | 1 +
src/tools/gnm-solver.c | 62 ++++++++++++++++++++++++++++++----------
src/tools/gnm-solver.h | 5 +--
5 files changed, 63 insertions(+), 38 deletions(-)
---
diff --git a/plugins/glpk/gnm-glpk.c b/plugins/glpk/gnm-glpk.c
index 64d9b97..ed6528b 100644
--- a/plugins/glpk/gnm-glpk.c
+++ b/plugins/glpk/gnm-glpk.c
@@ -13,9 +13,6 @@
#include <glib/gstdio.h>
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
#define PRIVATE_KEY "::glpk::"
@@ -173,16 +170,16 @@ fail:
static void
-cb_child_exit (GPid pid, gint status, GnmGlpk *lp)
+gnm_glpk_child_exit (GnmSubSolver *subsol, gboolean normal, int code,
+ GnmGlpk *lp)
{
- GnmSubSolver *subsol = lp->parent;
GnmSolver *sol = GNM_SOLVER (subsol);
if (sol->status != GNM_SOLVER_STATUS_RUNNING)
return;
- if (WIFEXITED (status)) {
- switch (WEXITSTATUS (status)) {
+ if (normal) {
+ switch (code) {
case 0: {
GnmLocale *locale = gnm_push_C_locale ();
gnm_glpk_read_solution (lp);
@@ -256,13 +253,16 @@ gnm_glpk_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
{
GnmSubSolver *subsol = GNM_SUB_SOLVER (sol);
gboolean ok;
- gchar *argv[6];
+ gchar *argv[7];
int argc = 0;
+ GnmSolverParameters *param = sol->params;
g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
argv[argc++] = (gchar *)"glpsol";
- // FIXME: Handle automatic scaling.
+ argv[argc++] = (gchar *)(param->options.automatic_scaling
+ ? "--scale"
+ : "--noscale");
argv[argc++] = (gchar *)"--write";
argv[argc++] = lp->result_filename;
argv[argc++] = (gchar *)"--cpxlp";
@@ -272,7 +272,6 @@ gnm_glpk_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
ok = gnm_sub_solver_spawn (subsol, argv,
cb_child_setup, NULL,
- (GChildWatchFunc)cb_child_exit, lp,
NULL, NULL,
NULL, NULL,
err);
@@ -311,6 +310,7 @@ glpk_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
g_signal_connect (res, "prepare", G_CALLBACK (gnm_glpk_prepare), lp);
g_signal_connect (res, "start", G_CALLBACK (gnm_glpk_start), lp);
g_signal_connect (res, "stop", G_CALLBACK (gnm_glpk_stop), lp);
+ g_signal_connect (res, "child-exit", G_CALLBACK (gnm_glpk_child_exit), lp);
g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
(GDestroyNotify)gnm_glpk_final);
diff --git a/plugins/lpsolve/gnm-lpsolve.c b/plugins/lpsolve/gnm-lpsolve.c
index 968974b..f41e5d4 100644
--- a/plugins/lpsolve/gnm-lpsolve.c
+++ b/plugins/lpsolve/gnm-lpsolve.c
@@ -8,9 +8,6 @@
#include <gsf/gsf-impl-utils.h>
#include <glib/gi18n-lib.h>
#include <string.h>
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
#define PRIVATE_KEY "::lpsolve::"
@@ -153,19 +150,19 @@ cb_read_stdout (GIOChannel *channel, GIOCondition cond, GnmLPSolve *lp)
static void
-cb_child_exit (GPid pid, gint status, GnmLPSolve *lp)
+gnm_lpsolve_child_exit (GnmSubSolver *subsol, gboolean normal, int code,
+ GnmLPSolve *lp)
{
- GnmSubSolver *subsol = lp->parent;
GnmSolver *sol = GNM_SOLVER (subsol);
GnmSolverStatus new_status = GNM_SOLVER_STATUS_DONE;
if (sol->status != GNM_SOLVER_STATUS_RUNNING)
return;
- if (WIFEXITED (status)) {
+ if (normal) {
GnmSolverResult *r;
- switch (WEXITSTATUS (status)) {
+ switch (code) {
case 0: /* Optimal */
gnm_sub_solver_flush (subsol);
if (lp->result)
@@ -270,7 +267,6 @@ gnm_lpsolve_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
ok = gnm_sub_solver_spawn (subsol, argv,
cb_child_setup, NULL,
- (GChildWatchFunc)cb_child_exit, lp,
(GIOFunc)cb_read_stdout, lp,
NULL, NULL,
err);
@@ -309,6 +305,7 @@ lpsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
g_signal_connect (res, "prepare", G_CALLBACK (gnm_lpsolve_prepare), lp);
g_signal_connect (res, "start", G_CALLBACK (gnm_lpsolve_start), lp);
g_signal_connect (res, "stop", G_CALLBACK (gnm_lpsolve_stop), lp);
+ g_signal_connect (res, "child-exit", G_CALLBACK (gnm_lpsolve_child_exit), lp);
g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
(GDestroyNotify)gnm_lpsolve_final);
diff --git a/src/gnm-marshalers.list b/src/gnm-marshalers.list
index 2fff383..bbe5bbd 100644
--- a/src/gnm-marshalers.list
+++ b/src/gnm-marshalers.list
@@ -27,3 +27,4 @@ INT:INT
POINTER:INT,INT
POINTER:VOID
VOID:INT,INT
+VOID:BOOLEAN,INT
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 51a7f82..44ddd8c 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -22,6 +22,16 @@
#include <sys/wait.h>
#endif
+#ifdef G_OS_WIN32
+#include <windows.h>
+#ifndef WIFEXITED
+#define WIFEXITED(x) ((x) != STILL_ACTIVE)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(x) (x)
+#endif
+#endif
+
/* ------------------------------------------------------------------------- */
gboolean
@@ -727,6 +737,7 @@ enum {
SOL_SIG_PREPARE,
SOL_SIG_START,
SOL_SIG_STOP,
+ SOL_SIG_CHILD_EXIT,
SOL_SIG_LAST
};
@@ -1055,6 +1066,16 @@ gnm_solver_class_init (GObjectClass *object_class)
gnm__BOOLEAN__POINTER,
G_TYPE_BOOLEAN, 1,
G_TYPE_POINTER);
+
+ solver_signals[SOL_SIG_CHILD_EXIT] =
+ g_signal_new ("child-exit",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GnmSolverClass, child_exit),
+ NULL, NULL,
+ gnm__VOID__BOOLEAN_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_BOOLEAN, G_TYPE_INT);
}
GSF_CLASS (GnmSolver, gnm_solver,
@@ -1096,12 +1117,14 @@ gnm_sub_solver_clear (GnmSubSolver *subsol)
if (subsol->child_watch) {
g_source_remove (subsol->child_watch);
subsol->child_watch = 0;
- subsol->child_exit = NULL;
- subsol->exit_data = NULL;
}
if (subsol->child_pid) {
+#ifdef G_OS_WIN32
+ TerminateProcess (subsol->child_pid, 127);
+#else
kill (subsol->child_pid, SIGKILL);
+#endif
g_spawn_close_pid (subsol->child_pid);
subsol->child_pid = (GPid)0;
}
@@ -1159,28 +1182,37 @@ gnm_sub_solver_init (GnmSubSolver *subsol)
static void
cb_child_exit (GPid pid, gint status, GnmSubSolver *subsol)
{
- if (gnm_solver_debug ()) {
- if (WIFEXITED (status))
+ gboolean normal = WIFEXITED (status);
+ int code;
+
+ subsol->child_watch = 0;
+
+ if (normal) {
+ code = WEXITSTATUS (status);
+ if (gnm_solver_debug ())
g_printerr ("Solver process exited with code %d\n",
- WEXITSTATUS (status));
- else if (WIFSIGNALED (status))
+ code);
+#ifndef G_OS_WIN32
+ } else if (WIFSIGNALED (status)) {
+ code = WTERMSIG (status);
+ if (gnm_solver_debug ())
g_printerr ("Solver process received signal %d\n",
- WTERMSIG (status));
- else
- g_printerr ("Solver process exited with status 0x%x\n",
- status);
+ code);
+#endif
+ } else {
+ code = -1;
+ g_printerr ("Solver process exited with status 0x%x\n",
+ status);
}
- subsol->child_watch = 0;
- if (subsol->child_exit)
- subsol->child_exit (pid, status, subsol->exit_data);
+ g_signal_emit (subsol, solver_signals[SOL_SIG_CHILD_EXIT], 0,
+ normal, code);
}
gboolean
gnm_sub_solver_spawn (GnmSubSolver *subsol,
char **argv,
GSpawnChildSetupFunc child_setup, gpointer setup_data,
- GChildWatchFunc child_exit, gpointer exit_data,
GIOFunc io_stdout, gpointer stdout_data,
GIOFunc io_stderr, gpointer stderr_data,
GError **err)
@@ -1224,8 +1256,6 @@ gnm_sub_solver_spawn (GnmSubSolver *subsol,
if (!ok)
goto fail;
- subsol->child_exit = child_exit;
- subsol->exit_data = exit_data;
subsol->child_watch =
g_child_watch_add (subsol->child_pid,
(GChildWatchFunc)cb_child_exit, subsol);
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 7a6adad..83722de 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -207,6 +207,7 @@ typedef struct {
gboolean (*start) (GnmSolver *solver,
WorkbookControl *wbc, GError **err);
gboolean (*stop) (GnmSolver *solver, GError **err);
+ gboolean (*child_exit) (GnmSolver *solver, gboolean normal, int code);
} GnmSolverClass;
GType gnm_solver_get_type (void);
@@ -250,9 +251,6 @@ typedef struct {
GPid child_pid;
guint child_watch;
- GChildWatchFunc child_exit;
- gpointer exit_data;
-
gint fd[3];
GIOChannel *channels[3];
guint channel_watches[3];
@@ -272,7 +270,6 @@ gboolean gnm_sub_solver_spawn
(GnmSubSolver *subsol,
char **argv,
GSpawnChildSetupFunc child_setup, gpointer setup_data,
- GChildWatchFunc child_exit, gpointer exit_data,
GIOFunc io_stdout, gpointer stdout_data,
GIOFunc io_stderr, gpointer stderr_data,
GError **err);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]