aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authoripkn <ipknhama@gmail.com>2014-08-16 12:10:19 -0400
committeripkn <ipknhama@gmail.com>2014-08-16 12:10:19 -0400
commit79bbdfebfaff295f468bd9e2d46e8106693eb113 (patch)
tree69631e94eb3eb526fc1b1242177da3131de974ca /include
parent9b208fdaee0c4b1f757bf4e6c7d39fa03943fdf4 (diff)
downloadcrow-79bbdfebfaff295f468bd9e2d46e8106693eb113.tar.gz
crow-79bbdfebfaff295f468bd9e2d46e8106693eb113.zip
fixed multithread crash
Diffstat (limited to 'include')
-rw-r--r--include/dumb_timer_queue.h31
-rw-r--r--include/http_connection.h36
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{};