Browse Source

The clish utility will not use threads by default. The appropriate API is implemented.

git-svn-id: https://klish.googlecode.com/svn/trunk@241 0eaa4687-2ee9-07dd-09d9-bcdd2d2dd5fb
Serj Kalichev 13 years ago
parent
commit
995638b463
4 changed files with 87 additions and 52 deletions
  1. 5 6
      bin/clish.cpp
  2. 2 0
      clish/shell.h
  3. 2 5
      clish/shell/private.h
  4. 78 41
      clish/shell/shell_spawn.c

+ 5 - 6
bin/clish.cpp

@@ -42,18 +42,17 @@ int main(int argc, const char **argv)
 	if(argc > 1) {
 		int i = 1;
 		while(argc--) {
-			/* run the commands in the file */
-			result = clish_shell_spawn_from_file(shell,
-				NULL, argv[i++]);
+			/* Run the commands from the file */
+			result = clish_shell_from_file(shell, argv[i++]);
 		}
 	} else {
-		/* spawn the shell */
-		result = clish_shell_spawn_and_wait(shell, NULL);
+		/* The interactive shell */
+		result = clish_shell_loop(shell);
 	}
 
 	/* Cleanup */
 	clish_shell_delete(shell);
 
 	return result ? 0 : -1;
- }
+}
 //---------------------------------------------------------

+ 2 - 0
clish/shell.h

@@ -344,7 +344,9 @@ int clish_shell_spawn_and_wait(clish_shell_t * instance,
 	const pthread_attr_t * attr);
 bool_t clish_shell_spawn_from_file(clish_shell_t * instance,
 	const pthread_attr_t * attr, const char *filename);
+bool_t clish_shell_from_file(clish_shell_t * instance, const char *filename);
 void clish_shell_load_files(clish_shell_t * instance);
+bool_t clish_shell_loop(clish_shell_t * instance);
 
 _END_C_DECL
 #endif				/* _clish_shell_h */

+ 2 - 5
clish/shell/private.h

@@ -81,16 +81,13 @@ struct clish_shell_s {
  */
 void
 clish_shell_iterator_init(clish_shell_iterator_t * iter,
-			  clish_nspace_visibility_t field);
+	clish_nspace_visibility_t field);
 
 /**
  * get the next command which is an extension of the specified line 
  */
 const clish_command_t *clish_shell_find_next_completion(const clish_shell_t *
-							instance,
-							const char *line,
-							clish_shell_iterator_t *
-							iter);
+	instance, const char *line, clish_shell_iterator_t * iter);
 /** 
  * Push the specified file handle on to the stack of file handles
  * for this shell. The specified file will become the source of 

+ 78 - 41
clish/shell/shell_spawn.c

@@ -111,39 +111,9 @@ void clish_shell_load_files(clish_shell_t * this)
 }
 
 /*-------------------------------------------------------- */
-/*
- * This is invoked when the thread ends or is cancelled.
- */
-static void clish_shell_thread_cleanup(clish_shell_t * this)
-{
-#ifdef __vxworks
-	int last_state;
-	/* we need to avoid recursion issues that exit in VxWorks */
-	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &last_state);
-#endif				/* __vxworks */
-
-/* Nothing to do now. The context will be free later. */
-
-#ifdef __vxworks
-	pthread_setcancelstate(last_state, &last_state);
-#endif				/* __vxworks */
-}
-
-/*-------------------------------------------------------- */
-/*
- * This provides the thread of execution for a shell instance
- */
-static void *clish_shell_thread(void *arg)
+static bool_t _loop(clish_shell_t * this, bool_t is_thread)
 {
 	bool_t running = BOOL_TRUE;
-	clish_shell_t *this = arg;
-	int last_type;
-
-	/* make sure we can only be cancelled at controlled points */
-	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &last_type);
-	/* register a cancellation handler */
-	pthread_cleanup_push((void (*)(void *))clish_shell_thread_cleanup, this);
-
 	/*
 	 * Check the shell isn't closing down
 	 */
@@ -152,13 +122,11 @@ static void *clish_shell_thread(void *arg)
 		(void)clish_shell_push_file(this,
 			fdopen(fileno(tinyrl__get_istream(this->tinyrl)),"r"), BOOL_TRUE);
 
-		pthread_testcancel();
+		if (is_thread)
+			pthread_testcancel();
 
 		/* Loop reading and executing lines until the user quits. */
 		while (running) {
-			const clish_command_t *cmd;
-			const clish_view_t *view;
-
 			if ((SHELL_STATE_SCRIPT_ERROR == this->state) &&
 			    (BOOL_TRUE == tinyrl__get_isatty(this->tinyrl))) {
 				/* interactive session doesn't automatically exit on error */
@@ -178,9 +146,50 @@ static void *clish_shell_thread(void *arg)
 				running = clish_shell_pop_file(this);
 			}
 			/* test for cancellation */
-			pthread_testcancel();
+			if (is_thread)
+				pthread_testcancel();
 		}
 	}
+
+	return BOOL_TRUE;
+}
+
+/*-------------------------------------------------------- */
+/*
+ * This is invoked when the thread ends or is cancelled.
+ */
+static void clish_shell_thread_cleanup(clish_shell_t * this)
+{
+#ifdef __vxworks
+	int last_state;
+	/* we need to avoid recursion issues that exit in VxWorks */
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &last_state);
+#endif				/* __vxworks */
+
+/* Nothing to do now. The context will be free later. */
+
+#ifdef __vxworks
+	pthread_setcancelstate(last_state, &last_state);
+#endif				/* __vxworks */
+}
+
+/*-------------------------------------------------------- */
+/*
+ * This provides the thread of execution for a shell instance
+ */
+static void *clish_shell_thread(void *arg)
+{
+	clish_shell_t *this = arg;
+	int last_type;
+
+	/* make sure we can only be cancelled at controlled points */
+	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &last_type);
+	/* register a cancellation handler */
+	pthread_cleanup_push((void (*)(void *))clish_shell_thread_cleanup, this);
+
+	if (this)
+		_loop(this, BOOL_TRUE);
+
 	/* be a good pthread citizen */
 	pthread_cleanup_pop(1);
 
@@ -219,9 +228,11 @@ int clish_shell_spawn_and_wait(clish_shell_t * this,
 	return clish_shell_wait(this);
 }
 
+
 /*-------------------------------------------------------- */
-bool_t clish_shell_spawn_from_file(clish_shell_t * this,
-	const pthread_attr_t * attr, const char *filename)
+static bool_t _from_file(clish_shell_t * this,
+	bool_t is_thread, const pthread_attr_t * attr,
+	const char *filename)
 {
 	bool_t result = BOOL_FALSE;
 	FILE *file;
@@ -233,12 +244,38 @@ bool_t clish_shell_spawn_from_file(clish_shell_t * this,
 	if (NULL == file)
 		return result;
 	tinyrl__set_istream(this->tinyrl, file);
-	/* spawn the thread and wait for it to exit */
-	result = clish_shell_spawn_and_wait(this, attr) ?
-		BOOL_TRUE : BOOL_FALSE;
+	if (is_thread) {
+		/* spawn the thread and wait for it to exit */
+		result = clish_shell_spawn_and_wait(this, attr) ?
+			BOOL_TRUE : BOOL_FALSE;
+	} else {
+		/* Don't use thread */
+		result = clish_shell_loop(this);
+	}
 	fclose(file);
 
 	return result;
 }
 
 /*-------------------------------------------------------- */
+bool_t clish_shell_spawn_from_file(clish_shell_t * this,
+	const pthread_attr_t * attr, const char *filename)
+{
+	return _from_file(this, BOOL_TRUE, attr, filename);
+}
+
+/*-------------------------------------------------------- */
+bool_t clish_shell_from_file(clish_shell_t * this,
+	const char *filename)
+{
+	return _from_file(this, BOOL_FALSE, NULL, filename);
+}
+
+
+/*-------------------------------------------------------- */
+bool_t clish_shell_loop(clish_shell_t * this)
+{
+	return _loop(this, BOOL_FALSE);
+}
+
+/*-------------------------------------------------------- */