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