| 155 | } |
| 156 | |
| 157 | void task::exec_internal() |
| 158 | { |
| 159 | task_state READY_STATE = TASK_STATE_READY; |
| 160 | task_state RUNNING_STATE = TASK_STATE_RUNNING; |
| 161 | bool notify_if_necessary = true; |
| 162 | |
| 163 | if (_state.compare_exchange_strong( |
| 164 | READY_STATE, TASK_STATE_RUNNING, std::memory_order_relaxed)) { |
| 165 | CHECK_EQ_MSG( |
| 166 | tls_dsn.magic, 0xdeadbeef, "thread is not inited with task::set_tls_dsn_context"); |
| 167 | |
| 168 | task *parent_task = tls_dsn.current_task; |
| 169 | tls_dsn.current_task = this; |
| 170 | |
| 171 | _spec->on_task_begin.execute(this); |
| 172 | |
| 173 | exec(); |
| 174 | |
| 175 | // after exec(), one shot tasks are still in "running". |
| 176 | // other tasks may call "set_retry" to reset tasks to "ready", |
| 177 | // like timers and rpc_response_tasks |
| 178 | if (_state.compare_exchange_strong(RUNNING_STATE, |
| 179 | TASK_STATE_FINISHED, |
| 180 | std::memory_order_release, |
| 181 | std::memory_order_relaxed)) { |
| 182 | _spec->on_task_end.execute(this); |
| 183 | clear_non_trivial_on_task_end(); |
| 184 | } else { |
| 185 | if (!_wait_for_cancel) { |
| 186 | // for retried tasks such as timer or rpc_response_task |
| 187 | notify_if_necessary = false; |
| 188 | _spec->on_task_end.execute(this); |
| 189 | |
| 190 | if (ERR_OK == _error) |
| 191 | enqueue(); |
| 192 | } else { |
| 193 | // for cancelled |
| 194 | if (_state.compare_exchange_strong(READY_STATE, |
| 195 | TASK_STATE_CANCELLED, |
| 196 | std::memory_order_release, |
| 197 | std::memory_order_relaxed)) { |
| 198 | _spec->on_task_cancelled.execute(this); |
| 199 | } |
| 200 | |
| 201 | // always call on_task_end() |
| 202 | _spec->on_task_end.execute(this); |
| 203 | |
| 204 | // for timer task, we must call reset_callback after cancelled, because we don't |
| 205 | // reset callback after exec() |
| 206 | clear_non_trivial_on_task_end(); |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | tls_dsn.current_task = parent_task; |
| 211 | } |
| 212 | |
| 213 | if (notify_if_necessary) { |
| 214 | if (signal_waiters()) { |
no test coverage detected