fix cin crash
This commit is contained in:
parent
274146229e
commit
afbbf4e8db
8 changed files with 63 additions and 22 deletions
|
|
@ -51,8 +51,7 @@ set( sources
|
|||
src/url.cpp
|
||||
src/process.cpp
|
||||
src/http_connection.cpp
|
||||
src/url.cpp
|
||||
# src/http_server.cpp
|
||||
src/http_server.cpp
|
||||
src/json_rpc_connection.cpp
|
||||
src/json_rpc_stream_connection.cpp
|
||||
src/json_rpc_tcp_connection.cpp
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ namespace fc {
|
|||
};
|
||||
|
||||
struct cin_t : virtual public istream {
|
||||
~cin_t();
|
||||
virtual size_t readsome( char* buf, size_t len );
|
||||
virtual istream& read( char* buf, size_t len );
|
||||
virtual bool eof()const;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef FC_MUTEX_HPP_
|
||||
#define FC_MUTEX_HPP_
|
||||
#pragma once
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/spin_yield_lock.hpp>
|
||||
|
||||
|
|
@ -107,4 +106,3 @@ namespace fc {
|
|||
|
||||
} // namespace fc
|
||||
|
||||
#endif // MACE_CMT_MUTEX_HPP_
|
||||
|
|
|
|||
11
include/fc/scoped_lock.hpp
Normal file
11
include/fc/scoped_lock.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
namespace fc {
|
||||
template<typename T>
|
||||
class scoped_lock {
|
||||
public:
|
||||
scoped_lock( T& l ):_lock(l) { _lock.lock(); }
|
||||
~scoped_lock() { _lock.unlock(); }
|
||||
T& _lock;
|
||||
};
|
||||
}
|
||||
|
|
@ -28,11 +28,11 @@ namespace fc {
|
|||
template<typename Other>
|
||||
shared_ptr( const shared_ptr<Other>& o )
|
||||
:_ptr(o.get()) {
|
||||
if(_ptr) _ptr->retain();
|
||||
if(_ptr != nullptr ) _ptr->retain();
|
||||
}
|
||||
|
||||
shared_ptr( T* t, bool inc = false )
|
||||
:_ptr(t) { if( inc ) t->retain(); }
|
||||
:_ptr(t) { if( inc && t != nullptr) t->retain(); }
|
||||
|
||||
shared_ptr():_ptr(nullptr){}
|
||||
|
||||
|
|
@ -42,25 +42,27 @@ namespace fc {
|
|||
}
|
||||
shared_ptr( shared_ptr& p ) {
|
||||
_ptr = p._ptr;
|
||||
if( _ptr ) _ptr->retain();
|
||||
if( _ptr != nullptr ) _ptr->retain();
|
||||
}
|
||||
shared_ptr( shared_ptr&& p ) {
|
||||
_ptr = p._ptr;
|
||||
p._ptr = nullptr;
|
||||
}
|
||||
~shared_ptr() { if( _ptr ) { _ptr->release(); } }
|
||||
~shared_ptr() { if( nullptr != _ptr ) { _ptr->release(); } }
|
||||
|
||||
shared_ptr& reset( T* v = 0, bool inc = false ) {
|
||||
shared_ptr& reset( T* v = nullptr, bool inc = false ) {
|
||||
if( v == _ptr ) return *this;
|
||||
if( _ptr ) _ptr->release();
|
||||
if( inc && nullptr != v ) v->retain();
|
||||
if( nullptr != _ptr ) _ptr->release();
|
||||
_ptr = v;
|
||||
if( _ptr && inc ) _ptr->retain();
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_ptr& operator=(const shared_ptr& p ) {
|
||||
shared_ptr tmp(p);
|
||||
fc_swap(tmp._ptr,_ptr);
|
||||
if( _ptr == p._ptr ) return *this;
|
||||
if( _ptr != nullptr ) _ptr->release();
|
||||
_ptr = p._ptr;
|
||||
if( _ptr != nullptr ) _ptr->retain();
|
||||
return *this;
|
||||
}
|
||||
shared_ptr& operator=(shared_ptr&& p ) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef _FC_SPIN_YIELD_LOCK_HPP_
|
||||
#define _FC_SPIN_YIELD_LOCK_HPP_
|
||||
#pragma once
|
||||
|
||||
namespace boost {
|
||||
template<typename T> class atomic;
|
||||
|
|
@ -38,4 +37,3 @@ namespace fc {
|
|||
|
||||
} // namespace fc
|
||||
|
||||
#endif // _FC_SPIN_YIELD_LOCK_HPP_
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@
|
|||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <fc/log.hpp>
|
||||
#include <fc/mutex.hpp>
|
||||
#include <fc/scoped_lock.hpp>
|
||||
#include <string>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
namespace fc {
|
||||
ostream& operator<<( ostream& o, const char* v ) {
|
||||
|
|
@ -32,18 +35,27 @@ namespace fc {
|
|||
buf[write_pos&0xfffff] = c;
|
||||
++write_pos;
|
||||
|
||||
auto tmp = read_ready; // copy read_ready because it is accessed from multiple threads
|
||||
fc::promise<void>::ptr tmp;
|
||||
{ // copy read_ready because it is accessed from multiple threads
|
||||
fc::scoped_lock<boost::mutex> lock( read_ready_mutex );
|
||||
tmp = read_ready;
|
||||
}
|
||||
if( tmp && !tmp->ready() ) {
|
||||
tmp->set_value();
|
||||
}
|
||||
std::cin.read(&c,1);
|
||||
}
|
||||
eof = true;
|
||||
auto tmp = read_ready; // copy read_ready because it is accessed from multiple threads
|
||||
fc::promise<void>::ptr tmp;
|
||||
{ // copy read_ready because it is accessed from multiple threads
|
||||
fc::scoped_lock<boost::mutex> lock( read_ready_mutex );
|
||||
tmp = read_ready;
|
||||
}
|
||||
if( tmp && !tmp->ready() ) {
|
||||
tmp->set_value();
|
||||
}
|
||||
}
|
||||
boost::mutex read_ready_mutex;
|
||||
fc::promise<void>::ptr read_ready;
|
||||
fc::promise<void>::ptr write_ready;
|
||||
|
||||
|
|
@ -105,17 +117,34 @@ namespace fc {
|
|||
return u;
|
||||
}
|
||||
|
||||
cin_t::~cin_t() {
|
||||
wlog( "~cin_t" );
|
||||
/*
|
||||
cin_buffer& b = get_cin_buffer();
|
||||
if( b.read_ready ) {
|
||||
b.read_ready->wait();
|
||||
}
|
||||
*/
|
||||
}
|
||||
istream& cin_t::read( char* buf, size_t len ) {
|
||||
cin_buffer& b = get_cin_buffer();
|
||||
do {
|
||||
while( !b.eof && (b.write_pos - b.read_pos)==0 ){
|
||||
// wait for more...
|
||||
fc::promise<void>::ptr rr( new fc::promise<void>() );
|
||||
b.read_ready = rr;
|
||||
// b.read_ready = rr;
|
||||
{ // copy read_ready because it is accessed from multiple threads
|
||||
fc::scoped_lock<boost::mutex> lock( b.read_ready_mutex );
|
||||
b.read_ready = rr;
|
||||
}
|
||||
if( b.write_pos - b.read_pos == 0 ) {
|
||||
rr->wait();
|
||||
}
|
||||
b.read_ready.reset();
|
||||
{ // copy read_ready because it is accessed from multiple threads
|
||||
fc::scoped_lock<boost::mutex> lock( b.read_ready_mutex );
|
||||
b.read_ready.reset();
|
||||
}
|
||||
}
|
||||
if( b.eof ) return *this;
|
||||
size_t r = readsome( buf, len );
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@
|
|||
|
||||
namespace fc {
|
||||
retainable::retainable()
|
||||
:_ref_count(1) { }
|
||||
:_ref_count(1) {
|
||||
static_assert( sizeof(_ref_count) == sizeof(boost::atomic<int32_t>), "failed to reserve enough space" );
|
||||
}
|
||||
|
||||
retainable::~retainable() {
|
||||
assert( _ref_count <= 0 );
|
||||
assert( _ref_count == 0 );
|
||||
}
|
||||
void retainable::retain() {
|
||||
|
|
@ -15,8 +18,8 @@ namespace fc {
|
|||
}
|
||||
|
||||
void retainable::release() {
|
||||
if( 1 == ((boost::atomic<int32_t>*)&_ref_count)->fetch_sub(1, boost::memory_order_release ) ) {
|
||||
boost::atomic_thread_fence(boost::memory_order_acquire);
|
||||
if( 1 == ((boost::atomic<int32_t>*)&_ref_count)->fetch_sub(1, boost::memory_order_release ) ) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue