Skip to content

Commit 3e81bb1

Browse files
committed
Task execution mechanism moved task state field from volatile to atomic
1 parent f368c32 commit 3e81bb1

File tree

6 files changed

+45
-37
lines changed

6 files changed

+45
-37
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*******************************************************************************
44

55
=== 1.0.31 ===
6+
* Task execution mechanism moved task state field from volatile to atomic.
67
* Updated LLTL hashing specifications.
78
* Fixed $XDG_CONFIG_HOME being ignored.
89

include/lsp-plug.in/ipc/IExecutor.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ namespace lsp
3333
class IExecutor
3434
{
3535
protected:
36-
static inline void change_task_state(ITask *task, ITask::task_state_t state)
36+
static inline void set_task_state(ITask *task, ITask::task_state_t state)
3737
{
38-
task->nState = state;
38+
atomic_store(&task->nState, state);
39+
}
40+
41+
static inline bool change_task_state(ITask *task, ITask::task_state_t old_state, ITask::task_state_t new_state)
42+
{
43+
return atomic_cas(&task->nState, old_state, new_state);
3944
}
4045

4146
static inline void link_task(ITask *tail, ITask *link)

include/lsp-plug.in/ipc/ITask.h

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (C) 2024 Linux Studio Plugins Project <https://lsp-plug.in/>
3-
* (C) 2024 Vladimir Sadovnikov <sadko4u@gmail.com>
2+
* Copyright (C) 2025 Linux Studio Plugins Project <https://lsp-plug.in/>
3+
* (C) 2025 Vladimir Sadovnikov <sadko4u@gmail.com>
44
*
55
* This file is part of lsp-runtime-lib
66
* Created on: 27 янв. 2016 г.
@@ -23,6 +23,7 @@
2323
#define LSP_PLUG_IN_IPC_ITASK_H_
2424

2525
#include <lsp-plug.in/runtime/version.h>
26+
#include <lsp-plug.in/common/atomic.h>
2627
#include <lsp-plug.in/common/status.h>
2728
#include <lsp-plug.in/ipc/IRunnable.h>
2829

@@ -50,7 +51,7 @@ namespace lsp
5051
ITask *pNext; // Pointer to next task queue
5152
ipc::IExecutor *pExecutor; // Nested executor if present
5253
int nCode; // Execution code
53-
volatile task_state_t nState; // Task state
54+
int nState; // Task state
5455

5556
protected:
5657
// Executor service
@@ -62,67 +63,65 @@ namespace lsp
6263
ITask();
6364
ITask(const ITask &) = delete;
6465
ITask(ITask &&) = delete;
65-
virtual ~ITask();
66+
virtual ~ITask() override;
6667

6768
ITask & operator = (const ITask &) = delete;
6869
ITask & operator = (ITask &&) = delete;
6970

7071
public:
71-
virtual status_t run();
72+
virtual status_t run() override;
7273

7374
public:
75+
/** Get current state of task
76+
*
77+
* @return current task state
78+
*/
79+
inline task_state_t state() const { return task_state_t(atomic_load(&nState)); }
80+
7481
/** Check that task status is idle
7582
*
7683
* @return true if task status is idle
7784
*/
78-
inline bool idle() const { return nState == TS_IDLE; };
85+
inline bool idle() const { return state() == TS_IDLE; }
7986

8087
/** Check that task status is submitted
8188
*
8289
* @return true if task status is submitted
8390
*/
84-
inline bool submitted() const { return nState == TS_SUBMITTED; };
91+
inline bool submitted() const { return state() == TS_SUBMITTED; }
8592

8693
/** Check that task status is running
8794
*
8895
* @return true if task status is running
8996
*/
90-
inline bool running() const { return nState == TS_RUNNING; };
97+
inline bool running() const { return state() == TS_RUNNING; }
9198

9299
/** Check that task status is completed
93100
*
94101
* @return true if task status is completed
95102
*/
96-
inline bool completed() const { return nState == TS_COMPLETED; };
103+
inline bool completed() const { return state() == TS_COMPLETED; }
97104

98105
/** Check that execution was successful
99106
*
100107
* @return true if execution was successful;
101108
*/
102-
inline bool successful() const { return successful(nCode); };
109+
inline bool successful() const { return successful(nCode); }
103110

104111
/** Get last execution code
105112
*
106113
* @return last execution code
107114
*/
108-
inline int code() const { return nCode; };
109-
110-
/** Get current state of task
111-
*
112-
* @return current task state
113-
*/
114-
inline task_state_t state() const {return nState; };
115+
inline int code() const { return nCode; }
115116

116-
/** Reset task state
117+
/**
118+
* Reset task state. The state can be reset only if task is in completed state.
117119
*
118-
* @return task state
120+
* @return true if task has been reset
119121
*/
120122
inline bool reset()
121123
{
122-
if (nState != TS_COMPLETED)
123-
return false;
124-
nState = TS_IDLE;
125-
return true;
124+
return atomic_cas(&nState, TS_COMPLETED, TS_IDLE);
126125
}
127126
};
128127

src/main/ipc/IExecutor.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ namespace lsp
3636

3737
void IExecutor::run_task(ITask *task)
3838
{
39-
task->nState = ITask::TS_RUNNING;
39+
atomic_store(&task->nState, ITask::TS_RUNNING);
4040
task->nCode = 0;
41+
4142
task->nCode = task->run();
42-
task->nState = ITask::TS_COMPLETED;
43+
44+
atomic_store(&task->nState, ITask::TS_COMPLETED);
4345

4446
// Run callback method
4547
task_finished(task);

src/main/ipc/ITask.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ namespace lsp
3131
pNext = NULL;
3232
pExecutor = NULL;
3333
nCode = 0;
34-
nState = TS_IDLE;
34+
35+
atomic_store(&nState, TS_IDLE);
3536
}
3637

3738
ITask::~ITask()

src/main/ipc/NativeExecutor.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,18 @@ namespace lsp
4949
bool NativeExecutor::submit(ITask *task)
5050
{
5151
lsp_trace("submit task=%p", task);
52-
// Check task state
53-
if (!task->idle())
52+
53+
// Update task state to SUBMITTED
54+
if (!change_task_state(task, ITask::TS_IDLE, ITask::TS_SUBMITTED))
5455
return false;
5556

5657
// Try to acquire critical section
5758
if (!atomic_trylock(nLock))
59+
{
60+
set_task_state(task, ITask::TS_IDLE);
5861
return false;
59-
60-
// Update task state to SUBMITTED
61-
change_task_state(task, ITask::TS_SUBMITTED);
62+
}
63+
lsp_finally { atomic_unlock(nLock); };
6264

6365
// Critical section acquired, bind new task
6466
// Check that queue is empty
@@ -68,8 +70,6 @@ namespace lsp
6870
pHead = task;
6971
pTail = task;
7072

71-
// Release critical section
72-
atomic_unlock(nLock);
7373
return true;
7474
}
7575

@@ -151,8 +151,8 @@ namespace lsp
151151

152152
status_t NativeExecutor::execute(void *params)
153153
{
154-
NativeExecutor *_this = reinterpret_cast<NativeExecutor *>(params);
155-
_this->run();
154+
NativeExecutor *self = reinterpret_cast<NativeExecutor *>(params);
155+
self->run();
156156
return STATUS_OK;
157157
}
158158

0 commit comments

Comments
 (0)