+ /* The state migration mechanism */
+ enum _state {
+ /* For the initialize_state */
+ CLIENT_NEW, // The initial state for the initialize_state or after Client::shutdown()
+ CLIENT_INITIALIZING, // At the beginning of the Client::init()
+ CLIENT_INITIALIZED, // At the end of CLient::init()
+
+ /* For the mount_state */
+ CLIENT_UNMOUNTED, // The initial state for the mount_state or after unmounted
+ CLIENT_MOUNTING, // At the beginning of Client::mount()
+ CLIENT_MOUNTED, // At the end of Client::mount()
+ CLIENT_UNMOUNTING, // At the beginning of the Client::_unmout()
+ };
+
+ typedef enum _state state_t;
+ using RWRef_t = RWRef<state_t>;
+
+ struct mount_state_t : public RWRefState<state_t> {
+ public:
+ bool is_valid_state(state_t state) const override {
+ switch (state) {
+ case Client::CLIENT_MOUNTING:
+ case Client::CLIENT_MOUNTED:
+ case Client::CLIENT_UNMOUNTING:
+ case Client::CLIENT_UNMOUNTED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ int check_reader_state(state_t require) const override {
+ if (require == Client::CLIENT_MOUNTING &&
+ (state == Client::CLIENT_MOUNTING || state == Client::CLIENT_MOUNTED))
+ return true;
+ else
+ return false;
+ }
+
+ /* The state migration check */
+ int check_writer_state(state_t require) const override {
+ if (require == Client::CLIENT_MOUNTING &&
+ state == Client::CLIENT_UNMOUNTED)
+ return true;
+ else if (require == Client::CLIENT_MOUNTED &&
+ state == Client::CLIENT_MOUNTING)
+ return true;
+ else if (require == Client::CLIENT_UNMOUNTING &&
+ state == Client::CLIENT_MOUNTED)
+ return true;
+ else if (require == Client::CLIENT_UNMOUNTED &&
+ state == Client::CLIENT_UNMOUNTING)
+ return true;
+ else
+ return false;
+ }
+
+ mount_state_t(state_t state, const char *lockname, uint64_t reader_cnt=0)
+ : RWRefState (state, lockname, reader_cnt) {}
+ ~mount_state_t() {}
+ };
+
+ struct initialize_state_t : public RWRefState<state_t> {
+ public:
+ bool is_valid_state(state_t state) const override {
+ switch (state) {
+ case Client::CLIENT_NEW:
+ case Client::CLIENT_INITIALIZING:
+ case Client::CLIENT_INITIALIZED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ int check_reader_state(state_t require) const override {
+ if (require == Client::CLIENT_INITIALIZED &&
+ state >= Client::CLIENT_INITIALIZED)
+ return true;
+ else
+ return false;
+ }
+
+ /* The state migration check */
+ int check_writer_state(state_t require) const override {
+ if (require == Client::CLIENT_INITIALIZING &&
+ (state == Client::CLIENT_NEW))
+ return true;
+ else if (require == Client::CLIENT_INITIALIZED &&
+ (state == Client::CLIENT_INITIALIZING))
+ return true;
+ else if (require == Client::CLIENT_NEW &&
+ (state == Client::CLIENT_INITIALIZED))
+ return true;
+ else
+ return false;
+ }
+
+ initialize_state_t(state_t state, const char *lockname, uint64_t reader_cnt=0)
+ : RWRefState (state, lockname, reader_cnt) {}
+ ~initialize_state_t() {}
+ };
+
+ struct mount_state_t mount_state;
+ struct initialize_state_t initialize_state;