diff options
Diffstat (limited to 'src/VBox/Main/src-all/ThreadTask.cpp')
-rw-r--r-- | src/VBox/Main/src-all/ThreadTask.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/VBox/Main/src-all/ThreadTask.cpp b/src/VBox/Main/src-all/ThreadTask.cpp new file mode 100644 index 00000000..3fd702e8 --- /dev/null +++ b/src/VBox/Main/src-all/ThreadTask.cpp @@ -0,0 +1,136 @@ +/* $Id: ThreadTask.cpp $ */ +/** @file + * Implementation of ThreadTask + */ + +/* + * Copyright (C) 2015-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include <iprt/errcore.h> +#include <iprt/thread.h> + +#include "VirtualBoxBase.h" +#include "ThreadTask.h" + +#define LOG_GROUP LOG_GROUP_MAIN_THREAD_TASK +#include "LoggingNew.h" + +/** + * Starts the task (on separate thread), consuming @a this. + * + * The function takes ownership of "this" instance (object instance which calls + * this function). And the function is responsible for deletion of "this" + * pointer in all cases. + * + * Possible way of usage: + * @code{.cpp} + HRESULT hr; + SomeTaskInheritedFromThreadTask *pTask = NULL; + try + { + pTask = new SomeTaskInheritedFromThreadTask(this); + if (!pTask->Init()) // some init procedure + throw E_FAIL; + } + catch (...) + { + if (pTask); + delete pTask; + return E_FAIL; + } + return pTask->createThread(); // pTask is always consumed + @endcode + * + * @sa createThreadWithType + * + * @note Always consumes @a this! + */ +HRESULT ThreadTask::createThread(void) +{ + return createThreadInternal(RTTHREADTYPE_MAIN_WORKER); +} + + +/** + * Same ThreadTask::createThread(), except it takes a thread type parameter. + * + * @param enmType The thread type. + * + * @note Always consumes @a this! + */ +HRESULT ThreadTask::createThreadWithType(RTTHREADTYPE enmType) +{ + return createThreadInternal(enmType); +} + + +/** + * Internal worker for ThreadTask::createThread, + * ThreadTask::createThreadWithType. + * + * @note Always consumes @a this! + */ +HRESULT ThreadTask::createThreadInternal(RTTHREADTYPE enmType) +{ + LogThisFunc(("Created \"%s\"\n", m_strTaskName.c_str())); + + mAsync = true; + int vrc = RTThreadCreate(NULL, + taskHandlerThreadProc, + (void *)this, + 0, + enmType, + 0, + m_strTaskName.c_str()); + if (RT_SUCCESS(vrc)) + return S_OK; + + mAsync = false; + delete this; + return E_FAIL; +} + + +/** + * Static method that can get passed to RTThreadCreate to have a + * thread started for a Task. + */ +/* static */ DECLCALLBACK(int) ThreadTask::taskHandlerThreadProc(RTTHREAD /* thread */, void *pvUser) +{ + if (pvUser == NULL) + return VERR_INVALID_POINTER; /* nobody cares */ + + ThreadTask *pTask = static_cast<ThreadTask *>(pvUser); + + LogFunc(("Started \"%s\"\n", pTask->m_strTaskName.c_str())); + + /* + * handler shall catch and process all possible cases as errors and exceptions. + */ + pTask->handler(); + + LogFunc(("Ended \"%s\"\n", pTask->m_strTaskName.c_str())); + + delete pTask; + return VINF_SUCCESS; +} + |