From: Piotr Kosko Date: Tue, 6 Oct 2015 11:51:09 +0000 (+0200) Subject: [Archive] Remove TODO about thread safety X-Git-Tag: submit/tizen/20151026.073646^2^2~47^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=508ed96d2d4345cd7e2ccafa3542d4f470e8f89b;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Archive] Remove TODO about thread safety [Feature] Execution moved to single background thread to ensure that all operations are done sequentially. [Verification] Code compiles without errors. All operations are done in one background thread. TCT passrate is 100%. Change-Id: Ie79e61413f258ae3ace3ae37c56ce942f24cd9fb Signed-off-by: Piotr Kosko --- diff --git a/src/archive/archive_callback_data.cc b/src/archive/archive_callback_data.cc index 2efbaefb..81bb8211 100755 --- a/src/archive/archive_callback_data.cc +++ b/src/archive/archive_callback_data.cc @@ -603,9 +603,6 @@ PlatformResult AddProgressCallback::executeOperation(ArchiveFilePtr archive_file LoggerD("Update decompressed size and entry list"); // update informations about decompressed size and entry list - // TODO FIXME need to resolve problem with access to file by - // more than one thread - return archive_file_ptr->updateListOfEntries(); } diff --git a/src/archive/archive_file.cc b/src/archive/archive_file.cc index e929740d..68e772d0 100755 --- a/src/archive/archive_file.cc +++ b/src/archive/archive_file.cc @@ -175,20 +175,20 @@ gboolean ArchiveFile::callErrorCallback(void* data) return false; } -void* ArchiveFile::taskManagerThread(void *data) +void ArchiveFile::taskManagerThread(gpointer data, gpointer user_data) { LoggerD("Entered"); ArchiveFileHolder* archive_file_holder = static_cast(data); if (!archive_file_holder) { LoggerE("archive_file_holder is null"); - return NULL; + return; } if (!archive_file_holder->ptr){ LoggerE("archive_file is null"); delete archive_file_holder; archive_file_holder = NULL; - return NULL; + return; } PlatformResult result(ErrorCode::NO_ERROR); @@ -235,7 +235,7 @@ void* ArchiveFile::taskManagerThread(void *data) delete archive_file_holder; archive_file_holder = NULL; - return NULL; + return; } PlatformResult ArchiveFile::addOperation(OperationCallbackData* callback) @@ -251,23 +251,21 @@ PlatformResult ArchiveFile::addOperation(OperationCallbackData* callback) size = m_task_queue.size(); } if(1 == size) { - pthread_t thread; ArchiveFileHolder* holder = new(std::nothrow) ArchiveFileHolder(); if(!holder) { LoggerE("Memory allocation error"); return PlatformResult(ErrorCode::UNKNOWN_ERR, "Memory allocation error"); } holder->ptr = shared_from_this(); - if (pthread_create(&thread, NULL, taskManagerThread, - static_cast(holder))) { - LoggerE("Thread creation failed"); - delete holder; - holder = NULL; - return PlatformResult(ErrorCode::UNKNOWN_ERR, "Thread creation failed"); - } - if (pthread_detach(thread)) { - LoggerE("Thread detachment failed"); + // operations would be executed asynchronously on one background thread + // (no risk of parallel operations on file) + if (!g_thread_pool_push(ArchiveManager::getInstance().getThreadPool(), + static_cast(holder), NULL)) { + LoggerE("Thread creation failed"); + delete holder; + holder = NULL; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Thread creation failed"); } } return PlatformResult(ErrorCode::NO_ERROR); diff --git a/src/archive/archive_file.h b/src/archive/archive_file.h index 61f6a6da..c81b86d7 100755 --- a/src/archive/archive_file.h +++ b/src/archive/archive_file.h @@ -156,7 +156,7 @@ private: static gboolean getEntriesTaskCompleteCB(void *data); static gboolean getEntryByNameTaskCompleteCB(void *data); - static void* taskManagerThread(void *data); + static void taskManagerThread(gpointer data, gpointer user_data); common::PlatformResult addOperation(OperationCallbackData* callback); static gboolean callErrorCallback(void* data); diff --git a/src/archive/archive_manager.cc b/src/archive/archive_manager.cc index 97a9998c..ebe59641 100755 --- a/src/archive/archive_manager.cc +++ b/src/archive/archive_manager.cc @@ -28,11 +28,16 @@ ArchiveManager::ArchiveManager(): m_next_unique_id(0) { LoggerD("Initialize ArchiveManager"); + // create thread pool with max threads = 1 to make API calls async but + // only one call at time + m_pool = g_thread_pool_new(ArchiveFile::taskManagerThread, NULL, 1, true, NULL); } ArchiveManager::~ArchiveManager() { LoggerD("Deinitialize ArchiveManager"); + //finish only current task and wait for thread to stop + g_thread_pool_free(m_pool, true, true); } ArchiveManager& ArchiveManager::getInstance() @@ -42,6 +47,11 @@ ArchiveManager& ArchiveManager::getInstance() return instance; } +GThreadPool* ArchiveManager::getThreadPool() +{ + return m_pool; +} + void ArchiveManager::abort(long operation_id) { LoggerD("Entered"); diff --git a/src/archive/archive_manager.h b/src/archive/archive_manager.h index 354edb09..fb9f19aa 100755 --- a/src/archive/archive_manager.h +++ b/src/archive/archive_manager.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "archive_file.h" #include "archive_callback_data.h" @@ -41,6 +42,7 @@ public: long addPrivData(ArchiveFilePtr archive_file_ptr); common::PlatformResult getPrivData(long handle, ArchiveFilePtr* archive_file); common::PlatformResult open(OpenCallbackData* callback); + GThreadPool* getThreadPool(); private: ArchiveManager(); @@ -51,6 +53,9 @@ private: ArchiveFileMap m_priv_map; long m_next_unique_id; + + //! Handler for thread pool + GThreadPool* m_pool; }; } // archive