2
Copyright (C) 2000 by Sean David Fleming
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License
8
as published by the Free Software Foundation; either version 2
9
of the License, or (at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
The GNU GPL can also be found at http://www.gnu.org
24
#define _BSD_SIGNALS 1
34
#include "interface.h"
36
/* top level data structure */
37
extern struct sysenv_pak sysenv;
43
/**********************************************/
44
/* execute task in thread created by the pool */
45
/**********************************************/
46
void task_process(struct task_pak *task, gpointer data)
51
if (task->status != QUEUED)
54
/* setup for current task */
56
/* TODO - should be mutex locking this */
57
task->status = RUNNING;
59
/* execute the primary task */
60
task->primary(task->ptr1, task);
62
/* execute the cleanup task */
63
/* TODO - can we run this after (ie in the main process to avoid thread lock) */
66
if (task->status != KILLED)
69
task->cleanup(task->ptr2);
70
task->status = COMPLETED;
76
/* job completion notification */
80
/***************************************************/
81
/* set up the thread pool to process task requests */
82
/***************************************************/
83
void task_queue_init(void)
85
#ifdef G_THREADS_ENABLED
88
if (!g_thread_supported())
90
/* TODO - disallow queueing of background tasks if this happens */
91
gui_text_show(ERROR, "Task queue initialization failed.\n");
94
sysenv.thread_pool = g_thread_pool_new((GFunc) task_process, NULL,
100
/*****************************/
101
/* terminate the thread pool */
102
/*****************************/
103
void task_queue_free(void)
105
g_thread_pool_free(sysenv.thread_pool, TRUE, FALSE);
108
/*************************/
109
/* free a task structure */
110
/*************************/
111
void task_free(gpointer data)
113
struct task_pak *task = data;
115
g_assert(task != NULL);
119
g_free(task->message);
120
g_free(task->status_file);
123
fclose(task->status_fp);
125
g_string_free(task->status_text, TRUE);
130
/****************************/
131
/* submit a background task */
132
/****************************/
133
void task_new(const gchar *label,
134
gpointer func1, gpointer arg1,
135
gpointer func2, gpointer arg2,
138
struct task_pak *task;
140
/* duplicate the task data */
141
task = g_malloc(sizeof(struct task_pak));
142
sysenv.task_list = g_slist_prepend(sysenv.task_list, task);
144
task->status = QUEUED;
146
task->message = NULL;
149
task->progress = 0.0;
150
task->locked_model = model;
152
task->status_file = NULL;
153
task->status_fp = NULL;
154
task->status_index = -1;
155
task->status_text = g_string_new(NULL);
157
task->label = g_strdup(label);
158
task->primary = func1;
159
task->cleanup = func2;
164
((struct model_pak *) model)->locked = TRUE;
168
g_thread_pool_push(sysenv.thread_pool, task, NULL);
171
/**************************************/
172
/* platform independant task spawning */
173
/**************************************/
174
#define DEBUG_TASK_SYNC 0
175
gint task_sync(const gchar *command)
186
status = g_spawn_command_line_sync(command, NULL, NULL, NULL, &error);
188
/* setup the command vector */
189
argv = g_malloc(4 * sizeof(gchar *));
190
*(argv) = g_strdup("/bin/sh");
191
*(argv+1) = g_strdup("-c");
192
*(argv+2) = g_strdup(command);
194
status = g_spawn_sync(sysenv.cwd, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, &error);
199
printf("Error: %s\n", error->message);
204
/********************************************/
205
/* filter out unwanted lines in status file */
206
/********************************************/
207
gint task_status_keep(gint type, const gchar *line)
212
if (strstr(line, "CPU"))
214
if (strstr(line, " **"))
217
if (strstr(line, "="))
218
if (strstr(line, "energy"))
229
/**************************************************/
230
/* create descriptive string from the status file */
231
/**************************************************/
232
void task_status_update(struct task_pak *task)
237
g_assert(task != NULL);
239
/* setup any status file filtering */
241
if (g_ascii_strncasecmp("gulp", task->label, 4) == 0)
247
/* read in the status file */
248
if (task->status_file)
250
if (!task->status_fp)
252
task->status_index = 0;
253
/* exit if we've read in the file and closed it (due to completion) */
254
if (strlen((task->status_text)->str))
256
task->status_fp = fopen(task->status_file, "rt");
259
line = file_read_line(task->status_fp);
263
if (task_status_keep(filter, line))
265
g_string_append(task->status_text, line);
268
line = file_read_line(task->status_fp);
271
if (task->status == COMPLETED || task->status == KILLED)
273
fclose(task->status_fp);
274
task->status_fp = NULL;
2
Copyright (C) 2000 by Sean David Fleming
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License
8
as published by the Free Software Foundation; either version 2
9
of the License, or (at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
The GNU GPL can also be found at http://www.gnu.org
24
#define _BSD_SIGNALS 1
36
#include "interface.h"
38
/* top level data structure */
39
extern struct sysenv_pak sysenv;
45
/**********************************************/
46
/* execute task in thread created by the pool */
47
/**********************************************/
48
void task_process(struct task_pak *task, gpointer data)
53
if (task->status != QUEUED)
56
/* setup for current task */
58
/* TODO - should be mutex locking this */
59
task->status = RUNNING;
61
/* NB: the primary task needs to not do anything that could */
62
/* cause problems eg update GUI elements since this can cause conflicts */
64
/* execute the primary task */
65
task->primary(task->ptr1, task);
67
/* NB: GUI updates should ALL be done in the cleanup task, since we */
68
/* do the threads enter to avoid problems - this locks the GUI */
69
/* until we call the threads leave function at the end */
73
if (task->status != KILLED)
75
/* execute the cleanup task */
77
task->cleanup(task->ptr2);
78
task->status = COMPLETED;
84
/* job completion notification */
88
/***************************************************/
89
/* set up the thread pool to process task requests */
90
/***************************************************/
91
void task_queue_init(void)
93
#ifdef G_THREADS_ENABLED
96
if (!g_thread_supported())
98
/* TODO - disallow queueing of background tasks if this happens */
99
gui_text_show(ERROR, "Task queue initialization failed.\n");
102
sysenv.thread_pool = g_thread_pool_new((GFunc) task_process, NULL,
108
/*****************************/
109
/* terminate the thread pool */
110
/*****************************/
111
void task_queue_free(void)
113
g_thread_pool_free(sysenv.thread_pool, TRUE, FALSE);
116
/*************************/
117
/* free a task structure */
118
/*************************/
119
void task_free(gpointer data)
121
struct task_pak *task = data;
123
g_assert(task != NULL);
127
g_free(task->message);
128
g_free(task->status_file);
131
fclose(task->status_fp);
133
g_string_free(task->status_text, TRUE);
138
/****************************/
139
/* submit a background task */
140
/****************************/
141
/* TODO - only show certain tasks in the manager, since this */
142
/* could be used to do any tasks in the background - some of */
143
/* which may be slow GUI tasks we dont want to be cancellable */
144
void task_new(const gchar *label,
145
gpointer func1, gpointer arg1,
146
gpointer func2, gpointer arg2,
149
struct task_pak *task;
151
/* duplicate the task data */
152
task = g_malloc(sizeof(struct task_pak));
153
sysenv.task_list = g_slist_prepend(sysenv.task_list, task);
155
task->status = QUEUED;
157
task->message = NULL;
160
task->progress = 0.0;
161
task->locked_model = model;
163
task->status_file = NULL;
164
task->status_fp = NULL;
165
task->status_index = -1;
166
task->status_text = g_string_new(NULL);
168
task->label = g_strdup(label);
169
task->primary = func1;
170
task->cleanup = func2;
175
((struct model_pak *) model)->locked = TRUE;
179
g_thread_pool_push(sysenv.thread_pool, task, NULL);
182
/**************************************/
183
/* platform independant task spawning */
184
/**************************************/
185
#define DEBUG_TASK_SYNC 0
186
gint task_sync(const gchar *command)
200
/* setup the command vector */
201
argv = g_malloc(4 * sizeof(gchar *));
202
*(argv) = g_strdup("/bin/sh");
203
*(argv+1) = g_strdup("-c");
204
*(argv+2) = g_strdup(command);
206
status = g_spawn_sync(sysenv.cwd, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, &error);
211
printf("task_sync() error: %s\n", error->message);
216
/********************************************/
217
/* filter out unwanted lines in status file */
218
/********************************************/
219
gint task_status_keep(gint type, const gchar *line)
224
if (strstr(line, "CPU"))
226
if (strstr(line, " **"))
229
if (strstr(line, "="))
230
if (strstr(line, "energy"))
241
/**************************************************/
242
/* create descriptive string from the status file */
243
/**************************************************/
244
void task_status_update(struct task_pak *task)
249
g_assert(task != NULL);
251
/* setup any status file filtering */
253
if (g_ascii_strncasecmp("gulp", task->label, 4) == 0)
259
/* read in the status file */
260
if (task->status_file)
262
if (!task->status_fp)
264
task->status_index = 0;
265
/* exit if we've read in the file and closed it (due to completion) */
266
if (strlen((task->status_text)->str))
268
task->status_fp = fopen(task->status_file, "rt");
271
line = file_read_line(task->status_fp);
275
if (task_status_keep(filter, line))
277
g_string_append(task->status_text, line);
280
line = file_read_line(task->status_fp);
283
if (task->status == COMPLETED || task->status == KILLED)
285
fclose(task->status_fp);
286
task->status_fp = NULL;