• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2019 Huawei Technologies Co., Ltd
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 #include "minddata/dataset/util/service.h"
17 #include <thread>
18 
19 namespace mindspore {
20 namespace dataset {
ServiceStart()21 Status Service::ServiceStart() {
22   do {
23     UniqueLock lck(&state_lock_);
24     // No-op if it is already up or some other thread is
25     // in the process of bring it up.
26     if (state_ == STATE::kRunning || state_ == STATE::kStartInProg) {
27       return Status::OK();
28     }
29     // If a stop is in progress, we line up after it
30     // is done.
31     if (state_ == STATE::kStopInProg) {
32       std::this_thread::yield();
33     } else {
34       state_ = STATE::kStartInProg;
35       // At this point, we will let go of the lock. This allow others to proceed.
36       lck.Unlock();
37       // Call the real implementation from the derived class.
38       Status rc = DoServiceStart();
39       // If we hit any error, change the state back into the initial state.
40       // It is possible that the user may want to drive a clean up by calling
41       // ServiceStop but if it will end up in a loop because of the state is still
42       // kStartInProg.
43       if (rc.IsError()) {
44         lck.Lock();
45         state_ = STATE::kStopped;
46         lck.Unlock();
47         return rc;
48       }
49       // Lock again to change state.
50       lck.Lock();
51       state_ = STATE::kRunning;
52       return Status::OK();
53     }
54   } while (true);
55 }
56 
ServiceStop()57 Status Service::ServiceStop() noexcept {
58   do {
59     UniqueLock lck(&state_lock_);
60     // No-op if it is already stopped or some other thread is
61     // in the process of shutting it down
62     if (state_ == STATE::kStopped || state_ == STATE::kStopInProg) {
63       return Status::OK();
64     }
65     // If a start is in progress, we line up after it
66     // is done.
67     if (state_ == STATE::kStartInProg) {
68       std::this_thread::yield();
69     } else {
70       state_ = STATE::kStopInProg;
71       // At this point, we will let go of the lock. This allows others to proceed.
72       lck.Unlock();
73       RETURN_IF_NOT_OK(DoServiceStop());
74       // Lock again to change state.
75       lck.Lock();
76       state_ = STATE::kStopped;
77       return Status::OK();
78     }
79   } while (true);
80 }
81 }  // namespace dataset
82 }  // namespace mindspore
83