diff options
author | ipkn <ipknhama@gmail.com> | 2014-08-16 12:10:19 -0400 |
---|---|---|
committer | ipkn <ipknhama@gmail.com> | 2014-08-16 12:10:19 -0400 |
commit | 79bbdfebfaff295f468bd9e2d46e8106693eb113 (patch) | |
tree | 69631e94eb3eb526fc1b1242177da3131de974ca /include | |
parent | 9b208fdaee0c4b1f757bf4e6c7d39fa03943fdf4 (diff) | |
download | crow-79bbdfebfaff295f468bd9e2d46e8106693eb113.tar.gz crow-79bbdfebfaff295f468bd9e2d46e8106693eb113.zip |
fixed multithread crash
Diffstat (limited to 'include')
-rw-r--r-- | include/dumb_timer_queue.h | 31 | ||||
-rw-r--r-- | include/http_connection.h | 36 |
2 files changed, 42 insertions, 25 deletions
diff --git a/include/dumb_timer_queue.h b/include/dumb_timer_queue.h index 185725e..ebb8bb1 100644 --- a/include/dumb_timer_queue.h +++ b/include/dumb_timer_queue.h @@ -21,15 +21,36 @@ namespace crow return q; } - void add(std::function<void()> f) + using key = std::pair<dumb_timer_queue*, int>; + + void cancel(key& k) + { + auto self = k.first; + k.first = nullptr; + if (!self) + return; + self->mutex_.lock(); + unsigned int index = (unsigned int)(k.second - self->step_); + if (index < self->dq_.size()) + self->dq_[index].second = nullptr; + self->mutex_.unlock(); + } + + key add(std::function<void()> f) { + mutex_.lock(); dq_.emplace_back(std::chrono::steady_clock::now(), std::move(f)); + int ret = step_+dq_.size()-1; + mutex_.unlock(); + CROW_LOG_DEBUG << "timer add inside: " << this << ' ' << ret ; + return {this, ret}; } void process() { if (!io_service_) return; + mutex_.lock(); auto now = std::chrono::steady_clock::now(); while(!dq_.empty()) { @@ -38,10 +59,14 @@ namespace crow break; if (x.second) { - io_service_->post(std::move(x.second)); + CROW_LOG_DEBUG << "timer call: " << this << ' ' << step_; + //io_service_->post(std::move(x.second)); + x.second(); } dq_.pop_front(); + step_++; } + mutex_.unlock(); } void set_io_service(boost::asio::io_service& io_service) @@ -57,6 +82,8 @@ namespace crow int tick{5}; boost::asio::io_service* io_service_{}; std::deque<std::pair<decltype(std::chrono::steady_clock::now()), std::function<void()>>> dq_; + std::mutex mutex_; + int step_{}; }; } } diff --git a/include/http_connection.h b/include/http_connection.h index a25924d..3232476 100644 --- a/include/http_connection.h +++ b/include/http_connection.h @@ -70,6 +70,7 @@ namespace crow void handle() { + cancel_deadline_timer(); bool is_invalid_request = false; request req = parser_.to_request(); @@ -97,7 +98,6 @@ namespace crow if (!is_invalid_request) { - cancel_deadline_timer(); res.complete_request_handler_ = [this]{ this->complete_request(); }; res.is_alive_helper_ = [this]()->bool{ return socket_.is_open(); }; handler_->handle(req, res); @@ -117,8 +117,8 @@ namespace crow if (!socket_.is_open()) { - CROW_LOG_DEBUG << this << " delete (socket is closed) " << is_reading << ' ' << is_writing; - delete this; + //CROW_LOG_DEBUG << this << " delete (socket is closed) " << is_reading << ' ' << is_writing; + //delete this; return; } @@ -243,7 +243,6 @@ namespace crow bool ret = parser_.feed(buffer_.data(), bytes_transferred); if (ret && socket_.is_open() && !close_connection_) { - do_read(); error_while_reading = false; } } @@ -255,11 +254,12 @@ namespace crow socket_.close(); is_reading = false; CROW_LOG_DEBUG << this << " from read(1)"; - check_destory(); + check_destroy(); } else { start_deadline(); + do_read(); } }); } @@ -274,23 +274,22 @@ namespace crow is_writing = false; if (!ec) { - start_deadline(); if (close_connection_) { socket_.close(); CROW_LOG_DEBUG << this << " from write(1)"; - check_destory(); + check_destroy(); } } else { CROW_LOG_DEBUG << this << " from write(2)"; - check_destory(); + check_destroy(); } }); } - void check_destory() + void check_destroy() { CROW_LOG_DEBUG << this << " is_reading " << is_reading << " is_writing " << is_writing; if (!is_reading && !is_writing) @@ -302,11 +301,8 @@ namespace crow void cancel_deadline_timer() { - if (timer_cancel_helper) - { - *timer_cancel_helper = true; - timer_cancel_helper.release(); - } + CROW_LOG_DEBUG << this << " timer cancelled: " << timer_cancel_key_.first << ' ' << timer_cancel_key_.second; + detail::dumb_timer_queue::get_current_dumb_timer_queue().cancel(timer_cancel_key_); } void start_deadline(int timeout = 5) @@ -314,21 +310,15 @@ namespace crow auto& timer_queue = detail::dumb_timer_queue::get_current_dumb_timer_queue(); cancel_deadline_timer(); - timer_cancel_helper.reset(new bool{false}); - bool* p_is_cancelled = timer_cancel_helper.get(); - timer_queue.add([p_is_cancelled, this] + timer_cancel_key_ = timer_queue.add([this] { - if (*p_is_cancelled) - { - delete p_is_cancelled; - return; - } if (!socket_.is_open()) { return; } socket_.close(); }); + CROW_LOG_DEBUG << this << " timer added: " << timer_cancel_key_.first << ' ' << timer_cancel_key_.second; } private: @@ -349,7 +339,7 @@ namespace crow std::string date_str_; //boost::asio::deadline_timer deadline_; - std::unique_ptr<bool> timer_cancel_helper; + detail::dumb_timer_queue::key timer_cancel_key_; bool is_reading{}; bool is_writing{}; |