Run some actions in a separate thread

Some actions need to be threaded so we will run those in a
separate thread and deny requests to thread more actions if new
requests come in while a thread is already running.

Change-Id: I966c538e67860a6d8fe556e5a2eb7f7d1a987e74
Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
diff --git a/gui/objects.hpp b/gui/objects.hpp
index 124c926..44c2b36 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -257,6 +257,8 @@
 // GUIAction - Used for standard actions
 class GUIAction : public GUIObject, public ActionObject
 {
+	friend class ActionThread;
+
 public:
 	GUIAction(xml_node<>* node);
 
@@ -281,20 +283,19 @@
 protected:
 	int getKeyByName(std::string key);
 	int doAction(Action action);
+	bool needsToRunInSeparateThread(const Action& action);
 	void simulate_progress_bar(void);
 	int flash_zip(std::string filename, std::string pageName, int* wipe_cache);
 	void reinject_after_flash();
 	void operation_start(const string operation_name);
 	void operation_end(const int operation_status);
-	static void* command_thread(void *cookie);
-	static void* sideload_thread_fn(void *cookie);
-	static void* openrecoveryscript_thread_fn(void *cookie);
 	time_t Start;
 
 	// map action name to function pointer
 	typedef int (GUIAction::*execFunction)(std::string);
 	typedef std::map<std::string, execFunction> mapFunc;
 	static mapFunc mf;
+	static std::set<std::string> setActionsRunningInCallerThread;
 
 	// GUI actions
 	int reboot(std::string arg);
@@ -323,7 +324,7 @@
 	int screenshot(std::string arg);
 	int setbrightness(std::string arg);
 
-	// threaded actions
+	// (originally) threaded actions
 	int fileexists(std::string arg);
 	int flash(std::string arg);
 	int wipe(std::string arg);
@@ -355,6 +356,26 @@
 	int simulate;
 };
 
+class ActionThread
+{
+public:
+	ActionThread();
+	~ActionThread();
+
+	void threadActions(GUIAction *act, size_t start_index);
+	void run(void *data);
+private:
+	struct ThreadData
+	{
+		GUIAction *act;
+		size_t start_index;
+	};
+
+	pthread_t m_thread;
+	bool m_thread_running;
+	pthread_mutex_t m_act_lock;
+};
+
 class GUIConsole : public GUIObject, public RenderObject, public ActionObject
 {
 public: