1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * \author guonix
17 * \date Jan 2021
18 * \brief
19 */
20
21#include "bthread_task.h"
22#include "common/error_code.h"
23
24namespace proxima {
25namespace be {
26namespace query {
27
28BthreadTask::BthreadTask(std::string name_str)
29 : name_(std::move(name_str)),
30 status_(Task::Status::INITIALIZED),
31 exit_code_(0) {
32 bthread_mutex_init(&mutex_, nullptr);
33 bthread_cond_init(&cond_, nullptr);
34}
35
36BthreadTask::~BthreadTask() {
37 bthread_mutex_destroy(&mutex_);
38 bthread_cond_destroy(&cond_);
39}
40
41const std::string &BthreadTask::name() const {
42 return name_;
43}
44
45int BthreadTask::exit_code() const {
46 return exit_code_;
47}
48
49//! Invoke do_run interface
50int BthreadTask::run() {
51 return run_once();
52}
53
54Task::Status BthreadTask::status() const {
55 return status_.load();
56}
57
58//! Update task status, and notify listener if task have been finished
59void BthreadTask::status(Task::Status stat) {
60 if (stat == Status::FINISHED) {
61 bthread_mutex_lock(&mutex_);
62 status_.exchange(stat);
63 bthread_cond_signal(&cond_);
64 bthread_mutex_unlock(&mutex_);
65 } else {
66 status_.exchange(stat);
67 }
68}
69
70bool BthreadTask::running() const {
71 return status() == Task::Status::RUNNING;
72}
73
74bool BthreadTask::finished() const {
75 return status() == Task::Status::FINISHED;
76}
77
78int BthreadTask::run_once() {
79 Status stat = Status::SCHEDULED;
80 if (status_.compare_exchange_strong(stat, Status::RUNNING)) {
81 exit_code_ = do_run();
82 status(Task::Status::FINISHED);
83 return exit_code_;
84 } else if (stat == Status::RUNNING) {
85 return PROXIMA_BE_ERROR_CODE(TaskIsRunning);
86 } else if (stat == Status::FINISHED) {
87 return exit_code_;
88 }
89 return PROXIMA_BE_ERROR_CODE(RuntimeError);
90}
91
92//! Wait task until have been finished
93bool BthreadTask::wait_finish() {
94 bthread_mutex_lock(&mutex_);
95 if (!finished()) {
96 bthread_cond_wait(&cond_, &mutex_);
97 }
98 bthread_mutex_unlock(&mutex_);
99 return true;
100}
101
102} // namespace query
103} // namespace be
104} // namespace proxima
105