提交 f8c9c62d 编写于 作者: Y youngwolf

Always output service thread's ids.

Make basic_buffer's interfaces more similar to std::string.
Keep the capacity unchanged in basic_buffer::clear as std::string::clear does.
Make basic_buffer copyable.
上级 aaf8cd96
......@@ -13,6 +13,7 @@
#ifndef _ASCS_EXT_H_
#define _ASCS_EXT_H_
#include <initializer_list>
#include "../base.h"
//the size of the buffer used when receiving msg, must equal to or larger than the biggest msg size,
......@@ -52,23 +53,47 @@ public:
virtual const char* data() const {return std::string::data();}
};
//a substitute of std::string (just for unpacking scenario, many features are missing against std::string), because std::string
// has a small defect which is terrible for unpacking scenario, it cannot change its size without fill its buffer.
//a substitute of std::string, because std::string has a small defect which is terrible for unpacking scenario (and protobuf encoding),
// it cannot change its size without fill the extended buffers.
//please note that basic_buffer won't append '\0' to the end of the string (std::string will do), you must appen '\0' characters
// by your own if you want to print it via "%s" formatter, e.g. basic_buffer("123", 4), bb.append("abc", 4).
class basic_buffer
#if defined(_MSC_VER) && _MSC_VER <= 1800
: public asio::noncopyable
#endif
{
public:
basic_buffer() {do_detach();}
basic_buffer(size_t len) {do_detach(); do_assign(len);}
basic_buffer(size_t count, char c) {do_detach(); append(count, c);}
basic_buffer(const char* buff) {do_detach(); operator+=(buff);}
basic_buffer(const char* buff, size_t len) {do_detach(); append(buff, len);}
basic_buffer(std::initializer_list<char> ilist) {do_detach(); operator+=(ilist);}
basic_buffer(const basic_buffer& other) {do_detach(); append(other.buff, other.len);}
basic_buffer(basic_buffer&& other) {do_attach(other.buff, other.len, other.cap); other.do_detach();}
virtual ~basic_buffer() {clear();}
virtual ~basic_buffer() {clean();}
inline basic_buffer& operator=(basic_buffer&& other) {clean(); swap(other); return *this;}
inline basic_buffer& operator=(const basic_buffer& other) {resize(0); return operator+=(other);}
inline basic_buffer& operator=(char c) {resize(0); return operator+=(c);}
inline basic_buffer& operator=(const char* buff) {resize(0); return operator+=(buff);}
inline basic_buffer& operator=(std::initializer_list<char> ilist) {resize(0); return operator+=(ilist);}
inline basic_buffer& operator+=(const basic_buffer& other) {return append(other);}
inline basic_buffer& operator+=(char c) {return append(1, c);}
inline basic_buffer& operator+=(const char* buff) {return append(buff);}
inline basic_buffer& operator+=(std::initializer_list<char> ilist) {return append(ilist);}
basic_buffer& operator=(basic_buffer&& other) {clear(); swap(other); return *this;}
basic_buffer& append(const basic_buffer& other) {return append(other.data(), other.size());}
basic_buffer& append(size_t count, char c)
{
if (count > 0)
{
reserve(len + count); //no optimization for memory re-allocation, please reserve enough memory before appending data
memset(std::next(buff, len), c, count);
len += (unsigned) count;
}
return *this;
}
basic_buffer& append(const char* buff) {return append(buff, strlen(buff));}
basic_buffer& append(const char* _buff, size_t _len)
{
if (nullptr != _buff && _len > 0)
......@@ -80,8 +105,9 @@ public:
return *this;
}
basic_buffer& append(std::initializer_list<char> ilist) {return append(std::begin(ilist), ilist.size());}
void resize(size_t _len) //won't fill the extended buffer
void resize(size_t _len) //won't fill the extended buffers
{
if (_len <= cap)
len = (unsigned) _len;
......@@ -110,7 +136,8 @@ public:
size_t size() const {return nullptr == buff ? 0 : len;}
const char* data() const {return buff;}
void swap(basic_buffer& other) {std::swap(buff, other.buff); std::swap(len, other.len); std::swap(cap, other.cap);}
void clear() {free(buff); do_detach();}
void clear() {resize(0);}
void clean() {free(buff); do_detach();}
//functions needed by packer and unpacker
char* data() {return buff;}
......
......@@ -177,7 +177,7 @@ protected:
//protocol: length + body
//this unpacker has a fixed buffer (4000 bytes), if messages can be held in it, then this unpacker works just as the default unpacker,
// otherwise, a dynamic T will be created to hold big messages, then this unpacker works as the non_copy_unpacker.
//T can be std::string or basic_buffer, the latter will not fill its buffer in resize invocation, so is more efficient.
//T can be std::string or basic_buffer, the latter will not fill the extended buffers in resize invocation, so is more efficient.
template<typename T = basic_buffer>
class flexible_unpacker : public i_unpacker<T>
{
......@@ -355,7 +355,7 @@ private:
step = ASCS_HEAD_LEN;
}
big_msg.resize(cur_msg_len); //std::string will fill big_msg, which is totally not necessary for this scenario, but basic_buffer won't.
big_msg.resize(cur_msg_len); //std::string will fill extended buffers, which is totally not necessary for this scenario, but basic_buffer won't.
memcpy(const_cast<char*>(big_msg.data()), std::next(raw_buff.data(), step), remain_len);
}
......
......@@ -374,7 +374,6 @@ protected:
}
#endif
#ifdef ASCS_DECREASE_THREAD_AT_RUNTIME
size_t run(context* ctx)
{
size_t n = 0;
......@@ -382,6 +381,8 @@ protected:
std::stringstream os;
os << "service thread[" << std::this_thread::get_id() << "] begin.";
unified_out::info_out(os.str().data());
#ifdef ASCS_DECREASE_THREAD_AT_RUNTIME
++real_thread_num;
while (true)
{
......@@ -413,17 +414,17 @@ protected:
break;
}
}
#elif defined(ASCS_NO_TRY_CATCH)
n += ctx->io_context.run();
#else
while (true) try {n += ctx->io_context.run(); break;} catch (const std::exception& e) {if (!on_exception(e)) break;}
#endif
os.str("");
os << "service thread[" << std::this_thread::get_id() << "] end.";
unified_out::info_out(os.str().data());
return n;
}
#elif !defined(ASCS_NO_TRY_CATCH)
size_t run(context* ctx) {while (true) {try {return ctx->io_context.run();} catch (const std::exception& e) {if (!on_exception(e)) return 0;}}}
#else
size_t run(context* ctx) {return ctx->io_context.run();}
#endif
DO_SOMETHING_TO_ALL_MUTEX(service_can, service_can_mutex, std::lock_guard<std::mutex>)
DO_SOMETHING_TO_ONE_MUTEX(service_can, service_can_mutex, std::lock_guard<std::mutex>)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册