1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-02 17:22:27 +03:00

Reformat all code to coding standard

This commit is contained in:
Andrew Hutchings
2017-10-26 17:18:17 +01:00
parent 4985f3456e
commit 01446d1e22
1296 changed files with 403852 additions and 353747 deletions

642
utils/messageqcpp/bytestream.cpp Executable file → Normal file
View File

@ -1,4 +1,4 @@
/*
/*
Copyright (c) 2017, MariaDB
Copyright (C) 2014 InfiniDB, Inc.
@ -40,597 +40,627 @@ using namespace boost;
#define DEBUG_DUMP_STRINGS_LESS_THAN 0
namespace messageqcpp {
namespace messageqcpp
{
/* Copies only the data left to be read */
void ByteStream::doCopy(const ByteStream &rhs)
void ByteStream::doCopy(const ByteStream& rhs)
{
uint32_t rlen = rhs.length();
uint32_t rlen = rhs.length();
if (fMaxLen < rlen) {
delete [] fBuf;
fBuf = new uint8_t[rlen + ISSOverhead];
fMaxLen = rlen;
}
if (fMaxLen < rlen)
{
delete [] fBuf;
fBuf = new uint8_t[rlen + ISSOverhead];
fMaxLen = rlen;
}
memcpy(fBuf + ISSOverhead, rhs.fCurOutPtr, rlen);
fCurInPtr = fBuf + ISSOverhead + rlen;
fCurOutPtr = fBuf + ISSOverhead;
memcpy(fBuf + ISSOverhead, rhs.fCurOutPtr, rlen);
fCurInPtr = fBuf + ISSOverhead + rlen;
fCurOutPtr = fBuf + ISSOverhead;
}
ByteStream::ByteStream(const ByteStream& rhs) :
fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
{
//don't need to copy an empty ByteStream
if (rhs.fBuf)
doCopy(rhs);
//don't need to copy an empty ByteStream
if (rhs.fBuf)
doCopy(rhs);
}
ByteStream::ByteStream(const SBS &rhs) :
fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
ByteStream::ByteStream(const SBS& rhs) :
fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
{
if (rhs->fBuf)
doCopy(*rhs);
if (rhs->fBuf)
doCopy(*rhs);
}
ByteStream& ByteStream::operator=(const ByteStream& rhs)
{
if (this != &rhs)
{
if (rhs.fBuf)
doCopy(rhs);
else
{
delete [] fBuf;
fBuf = fCurInPtr = fCurOutPtr = 0;
fMaxLen = 0;
}
}
if (this != &rhs)
{
if (rhs.fBuf)
doCopy(rhs);
else
{
delete [] fBuf;
fBuf = fCurInPtr = fCurOutPtr = 0;
fMaxLen = 0;
}
}
return *this;
return *this;
}
ByteStream::ByteStream(uint32_t initSize) :
fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
{
if (initSize > 0) growBuf(initSize);
if (initSize > 0) growBuf(initSize);
}
void ByteStream::add(const uint8_t b)
{
if (fBuf == 0 || (static_cast<uint32_t>(fCurInPtr - fBuf) == fMaxLen + ISSOverhead))
growBuf();
if (fBuf == 0 || (static_cast<uint32_t>(fCurInPtr - fBuf) == fMaxLen + ISSOverhead))
growBuf();
*fCurInPtr++ = b;
*fCurInPtr++ = b;
}
void ByteStream::growBuf(uint32_t toSize)
{
if (fBuf == 0)
{
if (toSize == 0)
toSize = BlockSize;
else
toSize = ((toSize + BlockSize - 1) / BlockSize) * BlockSize;
fBuf = new uint8_t[toSize + ISSOverhead];
#ifdef ZERO_ON_NEW
memset(fBuf, 0, (toSize+ISSOverhead));
#endif
fMaxLen = toSize;
fCurInPtr =
fCurOutPtr = fBuf + ISSOverhead;
}
else
{
if (toSize == 0)
toSize = fMaxLen + BlockSize;
else
toSize = ((toSize + BlockSize - 1) / BlockSize) * BlockSize;
if (toSize <= fMaxLen)
return;
if (fBuf == 0)
{
if (toSize == 0)
toSize = BlockSize;
else
toSize = ((toSize + BlockSize - 1) / BlockSize) * BlockSize;
// Make sure we at least double the allocation
toSize = std::max(toSize, fMaxLen * 2);
uint8_t* t = new uint8_t[toSize + ISSOverhead];
uint32_t curOutOff = fCurOutPtr - fBuf;
uint32_t curInOff = fCurInPtr - fBuf;
memcpy(t, fBuf, fCurInPtr - fBuf);
fBuf = new uint8_t[toSize + ISSOverhead];
#ifdef ZERO_ON_NEW
memset(t+(fCurInPtr-fBuf), 0, (toSize+ISSOverhead)-(fCurInPtr-fBuf));
memset(fBuf, 0, (toSize + ISSOverhead));
#endif
delete [] fBuf;
fBuf = t;
fMaxLen = toSize;
fCurInPtr = fBuf + curInOff;
fCurOutPtr = fBuf + curOutOff;
}
fMaxLen = toSize;
fCurInPtr =
fCurOutPtr = fBuf + ISSOverhead;
}
else
{
if (toSize == 0)
toSize = fMaxLen + BlockSize;
else
toSize = ((toSize + BlockSize - 1) / BlockSize) * BlockSize;
if (toSize <= fMaxLen)
return;
// Make sure we at least double the allocation
toSize = std::max(toSize, fMaxLen * 2);
uint8_t* t = new uint8_t[toSize + ISSOverhead];
uint32_t curOutOff = fCurOutPtr - fBuf;
uint32_t curInOff = fCurInPtr - fBuf;
memcpy(t, fBuf, fCurInPtr - fBuf);
#ifdef ZERO_ON_NEW
memset(t + (fCurInPtr - fBuf), 0, (toSize + ISSOverhead) - (fCurInPtr - fBuf));
#endif
delete [] fBuf;
fBuf = t;
fMaxLen = toSize;
fCurInPtr = fBuf + curInOff;
fCurOutPtr = fBuf + curOutOff;
}
}
ByteStream& ByteStream::operator<<(const int8_t b)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 1U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((int8_t *) fCurInPtr) = b;
*((int8_t*) fCurInPtr) = b;
fCurInPtr += 1;
return *this;
return *this;
}
ByteStream& ByteStream::operator<<(const uint8_t b)
{
add(b);
add(b);
return *this;
return *this;
}
ByteStream& ByteStream::operator<<(const int16_t d)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 2U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((int16_t *) fCurInPtr) = d;
fCurInPtr += 2;
if (fBuf == 0 || (fCurInPtr - fBuf + 2U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
*((int16_t*) fCurInPtr) = d;
fCurInPtr += 2;
return *this;
}
ByteStream& ByteStream::operator<<(const uint16_t d)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 2U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((uint16_t *) fCurInPtr) = d;
fCurInPtr += 2;
if (fBuf == 0 || (fCurInPtr - fBuf + 2U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
*((uint16_t*) fCurInPtr) = d;
fCurInPtr += 2;
return *this;
}
ByteStream& ByteStream::operator<<(const int32_t q)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((int32_t *) fCurInPtr) = q;
fCurInPtr += 4;
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
*((int32_t*) fCurInPtr) = q;
fCurInPtr += 4;
return *this;
}
ByteStream& ByteStream::operator<<(const uint32_t q)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((uint32_t *) fCurInPtr) = q;
fCurInPtr += 4;
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
*((uint32_t*) fCurInPtr) = q;
fCurInPtr += 4;
return *this;
}
ByteStream& ByteStream::operator<<(const int64_t o)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 8U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((int64_t *) fCurInPtr) = o;
fCurInPtr += 8;
if (fBuf == 0 || (fCurInPtr - fBuf + 8U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
*((int64_t*) fCurInPtr) = o;
fCurInPtr += 8;
return *this;
}
ByteStream& ByteStream::operator<<(const uint64_t o)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 8U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((uint64_t *) fCurInPtr) = o;
fCurInPtr += 8;
if (fBuf == 0 || (fCurInPtr - fBuf + 8U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
*((uint64_t*) fCurInPtr) = o;
fCurInPtr += 8;
return *this;
}
ByteStream& ByteStream::operator<<(const string& s)
{
int32_t len = s.size();
int32_t len = s.size();
*this << len;
*this << len;
#if DEBUG_DUMP_STRINGS_LESS_THAN > 0
if (len < DEBUG_DUMP_STRINGS_LESS_THAN)
{
cerr << "bs: appending string len " << len << ": ";
for (size_t i = 0; i < len; i++)
{
char xxx=s.c_str()[i];
if (isprint(xxx)) cerr << xxx << ' ';
else cerr << "0x" << hex << ((unsigned)xxx&0xff) << dec << ' ';
}
cerr << endl;
}
#endif
append(reinterpret_cast<const uint8_t*>(s.c_str()), len);
return *this;
if (len < DEBUG_DUMP_STRINGS_LESS_THAN)
{
cerr << "bs: appending string len " << len << ": ";
for (size_t i = 0; i < len; i++)
{
char xxx = s.c_str()[i];
if (isprint(xxx)) cerr << xxx << ' ';
else cerr << "0x" << hex << ((unsigned)xxx & 0xff) << dec << ' ';
}
cerr << endl;
}
#endif
append(reinterpret_cast<const uint8_t*>(s.c_str()), len);
return *this;
}
ByteStream& ByteStream::operator>>(int8_t& b)
{
peek(b);
fCurOutPtr++;
return *this;
peek(b);
fCurOutPtr++;
return *this;
}
ByteStream& ByteStream::operator>>(uint8_t& b)
{
peek(b);
fCurOutPtr++;
return *this;
peek(b);
fCurOutPtr++;
return *this;
}
ByteStream& ByteStream::operator>>(int16_t& d)
{
peek(d);
fCurOutPtr += 2;
return *this;
peek(d);
fCurOutPtr += 2;
return *this;
}
ByteStream& ByteStream::operator>>(uint16_t& d)
{
peek(d);
fCurOutPtr += 2;
return *this;
peek(d);
fCurOutPtr += 2;
return *this;
}
ByteStream& ByteStream::operator>>(int32_t& q)
{
peek(q);
fCurOutPtr += 4;
return *this;
peek(q);
fCurOutPtr += 4;
return *this;
}
ByteStream& ByteStream::operator>>(uint32_t& q)
{
peek(q);
fCurOutPtr += 4;
return *this;
peek(q);
fCurOutPtr += 4;
return *this;
}
ByteStream& ByteStream::operator>>(int64_t& o)
{
peek(o);
fCurOutPtr += 8;
return *this;
peek(o);
fCurOutPtr += 8;
return *this;
}
ByteStream& ByteStream::operator>>(uint64_t& o)
{
peek(o);
fCurOutPtr += 8;
return *this;
peek(o);
fCurOutPtr += 8;
return *this;
}
ByteStream& ByteStream::operator>>(string& s)
{
peek(s);
fCurOutPtr += 4 + s.length();
return *this;
peek(s);
fCurOutPtr += 4 + s.length();
return *this;
}
ByteStream& ByteStream::operator>>(uint8_t*& bpr)
{
peek(bpr);
restart();
return *this;
peek(bpr);
restart();
return *this;
}
void ByteStream::peek(int8_t& b) const
{
if (length() < 1)
throw underflow_error("ByteStream::peek(int8_t): not enough data in stream to fill datatype");
if (length() < 1)
throw underflow_error("ByteStream::peek(int8_t): not enough data in stream to fill datatype");
b = *fCurOutPtr;
b = *fCurOutPtr;
}
void ByteStream::peek(uint8_t& b) const
{
if (length() < 1)
throw underflow_error("ByteStream::peek(uint8_t): not enough data in stream to fill datatype");
if (length() < 1)
throw underflow_error("ByteStream::peek(uint8_t): not enough data in stream to fill datatype");
b = *((int8_t *)fCurOutPtr);
b = *((int8_t*)fCurOutPtr);
}
void ByteStream::peek(int16_t& d) const
{
if (length() < 2)
throw underflow_error("ByteStream>int16_t: not enough data in stream to fill datatype");
if (length() < 2)
throw underflow_error("ByteStream>int16_t: not enough data in stream to fill datatype");
d = *((int16_t *) fCurOutPtr);
d = *((int16_t*) fCurOutPtr);
}
void ByteStream::peek(uint16_t& d) const
{
if (length() < 2)
throw underflow_error("ByteStream>uint16_t: not enough data in stream to fill datatype");
if (length() < 2)
throw underflow_error("ByteStream>uint16_t: not enough data in stream to fill datatype");
d = *((uint16_t *) fCurOutPtr);
d = *((uint16_t*) fCurOutPtr);
}
void ByteStream::peek(int32_t& q) const
{
if (length() < 4)
throw underflow_error("ByteStream>int32_t: not enough data in stream to fill datatype");
if (length() < 4)
throw underflow_error("ByteStream>int32_t: not enough data in stream to fill datatype");
q = *((int32_t *) fCurOutPtr);
q = *((int32_t*) fCurOutPtr);
}
void ByteStream::peek(uint32_t& q) const
{
if (length() < 4)
throw underflow_error("ByteStream>uint32_t: not enough data in stream to fill datatype");
if (length() < 4)
throw underflow_error("ByteStream>uint32_t: not enough data in stream to fill datatype");
q = *((uint32_t *) fCurOutPtr);
q = *((uint32_t*) fCurOutPtr);
}
void ByteStream::peek(int64_t& o) const
{
if (length() < 8)
throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype");
if (length() < 8)
throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype");
o = *((int64_t *) fCurOutPtr);
o = *((int64_t*) fCurOutPtr);
}
void ByteStream::peek(uint64_t& o) const
{
if (length() < 8)
throw underflow_error("ByteStream>uint64_t: not enough data in stream to fill datatype");
if (length() < 8)
throw underflow_error("ByteStream>uint64_t: not enough data in stream to fill datatype");
o = *((uint64_t *) fCurOutPtr);
o = *((uint64_t*) fCurOutPtr);
}
void ByteStream::peek(string& s) const
{
int32_t len;
int32_t len;
peek(len);
peek(len);
#if DEBUG_DUMP_STRINGS_LESS_THAN > 0
if (len < DEBUG_DUMP_STRINGS_LESS_THAN)
{
cerr << "bs: reading string len " << len << ": ";
for (size_t i = 0; i < len; i++)
{
char xxx = fCurOutPtr[4+i];
if (isprint(xxx)) cerr << xxx << ' ';
else cerr << "0x" << hex << ((unsigned)xxx&0xff) << dec << ' ';
}
cerr << endl;
}
#endif
if (len < 0)
throw logging::ProtocolError("expected a string");
//we know len >= 0 by now...
if (length() < static_cast<uint32_t>(len + 4))
{
if (len < DEBUG_DUMP_STRINGS_LESS_THAN)
{
cerr << "bs: reading string len " << len << ": ";
for (size_t i = 0; i < len; i++)
{
char xxx = fCurOutPtr[4 + i];
if (isprint(xxx)) cerr << xxx << ' ';
else cerr << "0x" << hex << ((unsigned)xxx & 0xff) << dec << ' ';
}
cerr << endl;
}
#endif
if (len < 0)
throw logging::ProtocolError("expected a string");
//we know len >= 0 by now...
if (length() < static_cast<uint32_t>(len + 4))
{
#if DEBUG_DUMP_STRINGS_LESS_THAN > 0
cerr << "bs: wanted " << len + 4 << " bytes, but there are only " << length() << " remaining" << endl;
cerr << "bs: wanted " << len + 4 << " bytes, but there are only " << length() << " remaining" << endl;
#endif
// "put back" the qbyte we just read for strong exception guarantee
throw underflow_error("ByteStream>string: not enough data in stream to fill datatype");
}
// "put back" the qbyte we just read for strong exception guarantee
throw underflow_error("ByteStream>string: not enough data in stream to fill datatype");
}
s.assign((char *) &fCurOutPtr[4], len);
s.assign((char*) &fCurOutPtr[4], len);
}
void ByteStream::load(const uint8_t* bp, uint32_t len)
{
// Do all the stuff that could throw an exception first
if (bp == 0 && len != 0)
throw invalid_argument("ByteStream::load: bp cannot equal 0 when len is not equal to 0");
// Do all the stuff that could throw an exception first
if (bp == 0 && len != 0)
throw invalid_argument("ByteStream::load: bp cannot equal 0 when len is not equal to 0");
uint32_t newMaxLen = (len + BlockSize - 1) / BlockSize * BlockSize;
uint32_t newMaxLen = (len + BlockSize - 1) / BlockSize * BlockSize;
if (len > fMaxLen) {
delete [] fBuf;
fBuf = new uint8_t[newMaxLen + ISSOverhead];
fMaxLen = newMaxLen;
}
if (len > fMaxLen)
{
delete [] fBuf;
fBuf = new uint8_t[newMaxLen + ISSOverhead];
fMaxLen = newMaxLen;
}
memcpy(fBuf + ISSOverhead, bp, len);
fCurOutPtr = fBuf + ISSOverhead;
fCurInPtr = fBuf + len + ISSOverhead;
memcpy(fBuf + ISSOverhead, bp, len);
fCurOutPtr = fBuf + ISSOverhead;
fCurInPtr = fBuf + len + ISSOverhead;
}
void ByteStream::append(const uint8_t* bp, uint32_t len)
{
if (len == 0)
return;
if (bp == 0)
throw invalid_argument("ByteStream::append: bp cannot equal 0 when len is not equal to 0");
if (len == 0)
return;
uint32_t newSize = static_cast<uint32_t>(fCurInPtr - fBuf + len);
if (bp == 0)
throw invalid_argument("ByteStream::append: bp cannot equal 0 when len is not equal to 0");
if (fBuf == 0 || (newSize > fMaxLen))
growBuf(newSize);
uint32_t newSize = static_cast<uint32_t>(fCurInPtr - fBuf + len);
memcpy(fCurInPtr, bp, len);
fCurInPtr += len;
if (fBuf == 0 || (newSize > fMaxLen))
growBuf(newSize);
memcpy(fCurInPtr, bp, len);
fCurInPtr += len;
}
void ByteStream::swap(ByteStream& rhs)
{
std::swap(fBuf, rhs.fBuf);
std::swap(fCurInPtr, rhs.fCurInPtr);
std::swap(fCurOutPtr, rhs.fCurOutPtr);
std::swap(fMaxLen, rhs.fMaxLen);
std::swap(fBuf, rhs.fBuf);
std::swap(fCurInPtr, rhs.fCurInPtr);
std::swap(fCurOutPtr, rhs.fCurOutPtr);
std::swap(fMaxLen, rhs.fMaxLen);
}
ifstream& operator>>(ifstream& ifs, ByteStream& bs)
{
int ifs_len;
ifs.seekg(0, ios::end);
ifs_len = ifs.tellg();
ifs.seekg(0, ios::beg);
boost::scoped_array<char> buf(new char[ifs_len]);
ifs.read(buf.get(), ifs_len);
bs.append(reinterpret_cast<const uint8_t*>(buf.get()), ifs_len);
return ifs;
int ifs_len;
ifs.seekg(0, ios::end);
ifs_len = ifs.tellg();
ifs.seekg(0, ios::beg);
boost::scoped_array<char> buf(new char[ifs_len]);
ifs.read(buf.get(), ifs_len);
bs.append(reinterpret_cast<const uint8_t*>(buf.get()), ifs_len);
return ifs;
}
bool ByteStream::operator==(const ByteStream& b) const
{
if (b.length() != length())
return false;
if (b.length() != length())
return false;
return (memcmp(fCurOutPtr, b.fCurOutPtr, length()) == 0);
return (memcmp(fCurOutPtr, b.fCurOutPtr, length()) == 0);
}
bool ByteStream::operator!=(const ByteStream& b) const
{
return !(*this == b);
return !(*this == b);
}
/* Serializeable interface */
void ByteStream::serialize(ByteStream &bs) const
void ByteStream::serialize(ByteStream& bs) const
{
bs << length();
bs.append(buf(), length());
bs << length();
bs.append(buf(), length());
}
void ByteStream::deserialize(ByteStream &bs)
void ByteStream::deserialize(ByteStream& bs)
{
uint32_t len;
uint32_t len;
restart();
bs >> len;
load(bs.buf(), len);
bs.advance(len);
restart();
bs >> len;
load(bs.buf(), len);
bs.advance(len);
}
void ByteStream::needAtLeast(size_t amount)
{
size_t currentSpace;
size_t currentSpace;
currentSpace = fMaxLen - (fCurInPtr - (fBuf + ISSOverhead));
if (currentSpace < amount)
growBuf(fMaxLen + amount);
currentSpace = fMaxLen - (fCurInPtr - (fBuf + ISSOverhead));
if (currentSpace < amount)
growBuf(fMaxLen + amount);
}
#ifdef _MSC_VER
#if BOOST_VERSION < 104500
ByteStream& ByteStream::operator<<(const uint32_t ui)
{
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
uint32_t q = ui;
*((uint32_t *) fCurInPtr) = q;
fCurInPtr += 4;
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
return *this;
uint32_t q = ui;
*((uint32_t*) fCurInPtr) = q;
fCurInPtr += 4;
return *this;
}
ByteStream& ByteStream::operator>>(uint32_t& ui)
{
uint32_t q;
peek(q);
fCurOutPtr += 4;
ui = q;
return *this;
uint32_t q;
peek(q);
fCurOutPtr += 4;
ui = q;
return *this;
}
#endif
#endif
ByteStream& ByteStream::operator<<(const ByteStream& bs)
{
uint32_t len = bs.length();
uint32_t len = bs.length();
*this << len;
*this << len;
append(bs.buf(), len);
append(bs.buf(), len);
return *this;
return *this;
}
ByteStream& ByteStream::operator>>(ByteStream& bs)
{
peek(bs);
fCurOutPtr += 4 + bs.length();
return *this;
peek(bs);
fCurOutPtr += 4 + bs.length();
return *this;
}
void ByteStream::peek(ByteStream& bs) const
{
uint32_t len;
uint32_t len;
peek(len);
peek(len);
if (length() < len)
throw underflow_error("ByteStream>ByteStream: not enough data in stream to fill datatype");
if (length() < len)
throw underflow_error("ByteStream>ByteStream: not enough data in stream to fill datatype");
bs.load(&fCurOutPtr[4], len);
bs.load(&fCurOutPtr[4], len);
}
ByteStream& ByteStream::operator<<(const uuid& u)
{
append(reinterpret_cast<const uint8_t*>(&u.data[0]), uuids::uuid::static_size());
return *this;
append(reinterpret_cast<const uint8_t*>(&u.data[0]), uuids::uuid::static_size());
return *this;
}
ByteStream& ByteStream::operator>>(uuid& u)
{
peek(u);
fCurOutPtr += uuids::uuid::static_size();
return *this;
peek(u);
fCurOutPtr += uuids::uuid::static_size();
return *this;
}
void ByteStream::peek(uuid& u) const
{
if (length() < uuids::uuid::static_size())
throw underflow_error("ByteStream>uuid: not enough data in stream to fill datatype");
if (length() < uuids::uuid::static_size())
throw underflow_error("ByteStream>uuid: not enough data in stream to fill datatype");
memcpy(&u.data[0], fCurOutPtr, uuids::uuid::static_size());
memcpy(&u.data[0], fCurOutPtr, uuids::uuid::static_size());
}
ByteStream& ByteStream::operator<<(const float f)
{
int sz = sizeof(float);
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((float *) fCurInPtr) = f;
fCurInPtr += sz;
int sz = sizeof(float);
return *this;
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((float*) fCurInPtr) = f;
fCurInPtr += sz;
return *this;
}
ByteStream& ByteStream::operator<<(const double d)
{
int sz = sizeof(double);
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((double *) fCurInPtr) = d;
fCurInPtr += sz;
int sz = sizeof(double);
return *this;
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
growBuf(fMaxLen + BlockSize);
*((double*) fCurInPtr) = d;
fCurInPtr += sz;
return *this;
}
ByteStream& ByteStream::operator>>(float& f)
{
peek(f);
fCurOutPtr += sizeof(float);
return *this;
peek(f);
fCurOutPtr += sizeof(float);
return *this;
}
ByteStream& ByteStream::operator>>(double& d)
{
peek(d);
fCurOutPtr += sizeof(double);
return *this;
peek(d);
fCurOutPtr += sizeof(double);
return *this;
}
void ByteStream::peek(float& f) const
{
if (length() < sizeof(float))
throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype");
if (length() < sizeof(float))
throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype");
f = *((float *) fCurOutPtr);
f = *((float*) fCurOutPtr);
}
void ByteStream::peek(double& d) const
{
if (length() < sizeof(double))
throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype");
if (length() < sizeof(double))
throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype");
d = *((double *) fCurOutPtr);
d = *((double*) fCurOutPtr);
}

891
utils/messageqcpp/bytestream.h Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,29 +10,31 @@ using namespace config;
int main(int argc, char** argv)
{
Config* cf = Config::makeConfig("./Columnstore.xml");
MessageQueueClient mqc("server1", cf);
Config* cf = Config::makeConfig("./Columnstore.xml");
MessageQueueClient mqc("server1", cf);
ByteStream obs;
string msg("Hello, world!");
ByteStream ibs;
uint32_t qb;
for (int i = 0; i < 10; i++)
{
obs.restart();
obs << msg;
cout << "writing " << obs.length() << " bytes to " << mqc.addr2String() << endl;
mqc.write(obs);
ibs = mqc.read();
ibs >> qb;
if (qb != 0)
{
string emsg("server did not ack message!");
cerr << emsg << endl;
throw runtime_error(emsg);
}
}
ByteStream obs;
string msg("Hello, world!");
ByteStream ibs;
uint32_t qb;
return 0;
for (int i = 0; i < 10; i++)
{
obs.restart();
obs << msg;
cout << "writing " << obs.length() << " bytes to " << mqc.addr2String() << endl;
mqc.write(obs);
ibs = mqc.read();
ibs >> qb;
if (qb != 0)
{
string emsg("server did not ack message!");
cerr << emsg << endl;
throw runtime_error(emsg);
}
}
return 0;
}

View File

@ -62,176 +62,199 @@ namespace messageqcpp
CompressedInetStreamSocket::CompressedInetStreamSocket()
{
config::Config *config = config::Config::makeConfig();
string val;
try {
val = config->getConfig("NetworkCompression", "Enabled");
}
catch(...) { }
if (val == "" || val == "Y")
useCompression = true;
else
useCompression = false;
config::Config* config = config::Config::makeConfig();
string val;
try
{
val = config->getConfig("NetworkCompression", "Enabled");
}
catch (...) { }
if (val == "" || val == "Y")
useCompression = true;
else
useCompression = false;
}
Socket * CompressedInetStreamSocket::clone() const
Socket* CompressedInetStreamSocket::clone() const
{
return new CompressedInetStreamSocket(*this);
return new CompressedInetStreamSocket(*this);
}
const SBS CompressedInetStreamSocket::read(const struct timespec* timeout, bool* isTimeOut,
Stats *stats) const
Stats* stats) const
{
SBS readBS, ret;
size_t uncompressedSize;
bool err;
readBS = InetStreamSocket::read(timeout, isTimeOut, stats);
if (readBS->length() == 0 || fMagicBuffer == BYTESTREAM_MAGIC)
return readBS;
SBS readBS, ret;
size_t uncompressedSize;
bool err;
err = alg.getUncompressedSize((char *) readBS->buf(), readBS->length(), &uncompressedSize);
if (!err)
return SBS(new ByteStream(0));
readBS = InetStreamSocket::read(timeout, isTimeOut, stats);
ret.reset(new ByteStream(uncompressedSize));
alg.uncompress((char *) readBS->buf(), readBS->length(), (char *) ret->getInputPtr());
ret->advanceInputPtr(uncompressedSize);
return ret;
if (readBS->length() == 0 || fMagicBuffer == BYTESTREAM_MAGIC)
return readBS;
err = alg.getUncompressedSize((char*) readBS->buf(), readBS->length(), &uncompressedSize);
if (!err)
return SBS(new ByteStream(0));
ret.reset(new ByteStream(uncompressedSize));
alg.uncompress((char*) readBS->buf(), readBS->length(), (char*) ret->getInputPtr());
ret->advanceInputPtr(uncompressedSize);
return ret;
}
void CompressedInetStreamSocket::write(const ByteStream &msg, Stats *stats)
void CompressedInetStreamSocket::write(const ByteStream& msg, Stats* stats)
{
size_t outLen=0;
uint32_t len = msg.length();
if (useCompression && (len > 512)) {
ByteStream smsg(alg.maxCompressedSize(len));
alg.compress((char *) msg.buf(), len, (char *) smsg.getInputPtr(), &outLen);
smsg.advanceInputPtr(outLen);
if (outLen < len)
do_write(smsg, COMPRESSED_BYTESTREAM_MAGIC, stats);
else
InetStreamSocket::write(msg, stats);
}
else
InetStreamSocket::write(msg, stats);
size_t outLen = 0;
uint32_t len = msg.length();
if (useCompression && (len > 512))
{
ByteStream smsg(alg.maxCompressedSize(len));
alg.compress((char*) msg.buf(), len, (char*) smsg.getInputPtr(), &outLen);
smsg.advanceInputPtr(outLen);
if (outLen < len)
do_write(smsg, COMPRESSED_BYTESTREAM_MAGIC, stats);
else
InetStreamSocket::write(msg, stats);
}
else
InetStreamSocket::write(msg, stats);
}
void CompressedInetStreamSocket::write(SBS msg, Stats *stats)
void CompressedInetStreamSocket::write(SBS msg, Stats* stats)
{
write(*msg, stats);
write(*msg, stats);
}
/* this was cut & pasted from InetStreamSocket;
/* this was cut & pasted from InetStreamSocket;
* is there a clean way to wrap ISS::accept()?
*/
const IOSocket CompressedInetStreamSocket::accept(const struct timespec* timeout)
{
int clientfd;
long msecs = 0;
int clientfd;
long msecs = 0;
struct pollfd pfd[1];
pfd[0].fd = socketParms().sd();
pfd[0].events = POLLIN;
struct pollfd pfd[1];
pfd[0].fd = socketParms().sd();
pfd[0].events = POLLIN;
if (timeout != 0)
{
msecs = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
if (poll(pfd, 1, msecs) != 1 || (pfd[0].revents & POLLIN) == 0 ||
pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
return IOSocket(new CompressedInetStreamSocket());
}
if (timeout != 0)
{
msecs = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
struct sockaddr sa;
socklen_t sl = sizeof(sa);
int e;
do
{
clientfd = ::accept(socketParms().sd(), &sa, &sl);
e = errno;
} while (clientfd < 0 && (e == EINTR ||
if (poll(pfd, 1, msecs) != 1 || (pfd[0].revents & POLLIN) == 0 ||
pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
return IOSocket(new CompressedInetStreamSocket());
}
struct sockaddr sa;
socklen_t sl = sizeof(sa);
int e;
do
{
clientfd = ::accept(socketParms().sd(), &sa, &sl);
e = errno;
}
while (clientfd < 0 && (e == EINTR ||
#ifdef ERESTART
e == ERESTART ||
e == ERESTART ||
#endif
#ifdef ECONNABORTED
e == ECONNABORTED ||
e == ECONNABORTED ||
#endif
false));
if (clientfd < 0)
{
string msg = "CompressedInetStreamSocket::accept: accept() error: ";
scoped_array<char> buf(new char[80]);
false));
if (clientfd < 0)
{
string msg = "CompressedInetStreamSocket::accept: accept() error: ";
scoped_array<char> buf(new char[80]);
#if STRERROR_R_CHAR_P
const char* p;
if ((p = strerror_r(e, buf.get(), 80)) != 0)
msg += p;
const char* p;
if ((p = strerror_r(e, buf.get(), 80)) != 0)
msg += p;
#else
int p;
if ((p = strerror_r(e, buf.get(), 80)) == 0)
msg += buf.get();
int p;
if ((p = strerror_r(e, buf.get(), 80)) == 0)
msg += buf.get();
#endif
throw runtime_error(msg);
}
throw runtime_error(msg);
}
if (fSyncProto)
{
/* send a byte to artificially synchronize with connect() on the remote */
char b = 'A';
int ret;
if (fSyncProto)
{
/* send a byte to artificially synchronize with connect() on the remote */
char b = 'A';
int ret;
ret = ::send(clientfd, &b, 1, 0);
e = errno;
if (ret < 0) {
ostringstream os;
char blah[80];
ret = ::send(clientfd, &b, 1, 0);
e = errno;
if (ret < 0)
{
ostringstream os;
char blah[80];
#if STRERROR_R_CHAR_P
const char* p;
if ((p = strerror_r(e, blah, 80)) != 0)
os << "CompressedInetStreamSocket::accept sync: " << p;
#else
int p;
if ((p = strerror_r(e, blah, 80)) == 0)
os << "CompressedInetStreamSocket::accept sync: " << blah;
#endif
::close(clientfd);
throw runtime_error(os.str());
}
else if (ret == 0) {
::close(clientfd);
throw runtime_error("CompressedInetStreamSocket::accept sync: got unexpected error code");
}
}
const char* p;
CompressedInetStreamSocket *ciss = new CompressedInetStreamSocket();
IOSocket ios;
sockaddr_in *sin = (sockaddr_in *) &sa;
if ((sin->sin_addr.s_addr == fSa.sin_addr.s_addr) ||
sin->sin_addr.s_addr == inet_addr("127.0.0.1"))
ciss->useCompression = false;
ios.setSocketImpl(ciss);
SocketParms sp;
sp = ios.socketParms();
sp.sd(clientfd);
ios.socketParms(sp);
ios.sa(&sa);
return ios;
if ((p = strerror_r(e, blah, 80)) != 0)
os << "CompressedInetStreamSocket::accept sync: " << p;
#else
int p;
if ((p = strerror_r(e, blah, 80)) == 0)
os << "CompressedInetStreamSocket::accept sync: " << blah;
#endif
::close(clientfd);
throw runtime_error(os.str());
}
else if (ret == 0)
{
::close(clientfd);
throw runtime_error("CompressedInetStreamSocket::accept sync: got unexpected error code");
}
}
CompressedInetStreamSocket* ciss = new CompressedInetStreamSocket();
IOSocket ios;
sockaddr_in* sin = (sockaddr_in*) &sa;
if ((sin->sin_addr.s_addr == fSa.sin_addr.s_addr) ||
sin->sin_addr.s_addr == inet_addr("127.0.0.1"))
ciss->useCompression = false;
ios.setSocketImpl(ciss);
SocketParms sp;
sp = ios.socketParms();
sp.sd(clientfd);
ios.socketParms(sp);
ios.sa(&sa);
return ios;
}
void CompressedInetStreamSocket::connect(const sockaddr* serv_addr)
{
sockaddr_in *sin = (sockaddr_in *) serv_addr;
if (sin->sin_addr.s_addr == fSa.sin_addr.s_addr ||
sin->sin_addr.s_addr == inet_addr("127.0.0.1"))
useCompression = false;
InetStreamSocket::connect(serv_addr);
sockaddr_in* sin = (sockaddr_in*) serv_addr;
if (sin->sin_addr.s_addr == fSa.sin_addr.s_addr ||
sin->sin_addr.s_addr == inet_addr("127.0.0.1"))
useCompression = false;
InetStreamSocket::connect(serv_addr);
}

View File

@ -35,23 +35,24 @@
#include "inetstreamsocket.h"
#include "idbcompress.h"
namespace messageqcpp {
namespace messageqcpp
{
class CompressedInetStreamSocket : public InetStreamSocket
{
public:
CompressedInetStreamSocket();
CompressedInetStreamSocket();
virtual Socket * clone() const;
virtual const SBS read(const struct timespec* timeout=0, bool* isTimeOut = NULL,
Stats *stats = NULL) const;
virtual void write(const ByteStream& msg, Stats *stats = NULL);
virtual void write(SBS msg, Stats *stats = NULL);
virtual const IOSocket accept(const struct timespec *timeout);
virtual void connect(const sockaddr *addr);
virtual Socket* clone() const;
virtual const SBS read(const struct timespec* timeout = 0, bool* isTimeOut = NULL,
Stats* stats = NULL) const;
virtual void write(const ByteStream& msg, Stats* stats = NULL);
virtual void write(SBS msg, Stats* stats = NULL);
virtual const IOSocket accept(const struct timespec* timeout);
virtual void connect(const sockaddr* addr);
private:
compress::IDBCompressInterface alg;
bool useCompression;
compress::IDBCompressInterface alg;
bool useCompression;
};
} //namespace messageqcpp

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,8 @@
class MessageQTestSuite;
namespace messageqcpp {
namespace messageqcpp
{
class IOSocket;
/// random # marking the beginning of a ByteStream in the stream
@ -56,207 +57,228 @@ const uint32_t COMPRESSED_BYTESTREAM_MAGIC = 0x14fbc138;
class InetStreamSocket : public Socket
{
public:
/** ctor
*
*/
explicit InetStreamSocket(size_t blocksize=ByteStream::BlockSize);
/** ctor
*
*/
explicit InetStreamSocket(size_t blocksize = ByteStream::BlockSize);
/** dtor
*
*/
virtual ~InetStreamSocket();
/** dtor
*
*/
virtual ~InetStreamSocket();
/** copy ctor
*
*/
InetStreamSocket(const InetStreamSocket& rhs);
/** copy ctor
*
*/
InetStreamSocket(const InetStreamSocket& rhs);
/** assign op
*
*/
virtual InetStreamSocket& operator=(const InetStreamSocket& rhs);
/** assign op
*
*/
virtual InetStreamSocket& operator=(const InetStreamSocket& rhs);
/** fSocket mutator
*
*/
inline virtual void socketParms(const SocketParms& socket);
/** fSocket mutator
*
*/
inline virtual void socketParms(const SocketParms& socket);
/** fSocket accessor
*
*/
inline virtual const SocketParms socketParms() const;
/** fSocket accessor
*
*/
inline virtual const SocketParms socketParms() const;
/** sockaddr mutator
*
*/
inline virtual void sa(const sockaddr* sa);
/** sockaddr mutator
*
*/
inline virtual void sa(const sockaddr* sa);
/** call socket() to get a sd
*
*/
virtual void open();
/** call socket() to get a sd
*
*/
virtual void open();
/** close the sd
*
*/
virtual void close();
/** close the sd
*
*/
virtual void close();
/** test if this socket is open
*
*/
inline virtual const bool isOpen() const;
/** test if this socket is open
*
*/
inline virtual const bool isOpen() const;
/** read a message from the socket
*
* wait for and return a message from the socket. The deafult timeout waits forever. Note that
* eventhough struct timespec has nanosecond resolution, this method only has milisecond resolution.
* @warning If you specify a timeout, the stream can be corrupted in certain
* extreme circumstances. The circumstance: receiving a portion of the message
* followed by a timeout. If the rest of the message is ever received, it
* will be misinterpreted by the following read(). Symptom: The caller will
* receive an incomplete ByteStream
* (do try-catch around all ">>" operations to detect underflow). Mitigation:
* the caller should not perform another read(). Caller should close the connection.
* The behavior will be unpredictable and possibly fatal.
* @note A fix is being reviewed but this is low-priority.
*/
virtual const SBS read(const struct timespec* timeout=0, bool* isTimeOut = NULL, Stats *stats = NULL) const;
/** read a message from the socket
*
* wait for and return a message from the socket. The deafult timeout waits forever. Note that
* eventhough struct timespec has nanosecond resolution, this method only has milisecond resolution.
* @warning If you specify a timeout, the stream can be corrupted in certain
* extreme circumstances. The circumstance: receiving a portion of the message
* followed by a timeout. If the rest of the message is ever received, it
* will be misinterpreted by the following read(). Symptom: The caller will
* receive an incomplete ByteStream
* (do try-catch around all ">>" operations to detect underflow). Mitigation:
* the caller should not perform another read(). Caller should close the connection.
* The behavior will be unpredictable and possibly fatal.
* @note A fix is being reviewed but this is low-priority.
*/
virtual const SBS read(const struct timespec* timeout = 0, bool* isTimeOut = NULL, Stats* stats = NULL) const;
/** write a message to the socket
*
* write a message to the socket
*/
virtual void write(const ByteStream& msg, Stats *stats = NULL);
virtual void write_raw(const ByteStream& msg, Stats *stats = NULL) const;
/** write a message to the socket
*
* write a message to the socket
*/
virtual void write(const ByteStream& msg, Stats* stats = NULL);
virtual void write_raw(const ByteStream& msg, Stats* stats = NULL) const;
/** this version of write takes ownership of the bytestream
*/
virtual void write(SBS msg, Stats *stats = NULL);
/** this version of write takes ownership of the bytestream
*/
virtual void write(SBS msg, Stats* stats = NULL);
/** bind to a port
*
*/
virtual void bind(const sockaddr* serv_addr);
/** bind to a port
*
*/
virtual void bind(const sockaddr* serv_addr);
/** listen for connections
*
*/
virtual void listen(int backlog=5);
/** listen for connections
*
*/
virtual void listen(int backlog = 5);
/** return an (accepted) IOSocket ready for I/O
*
*/
virtual const IOSocket accept(const struct timespec* timeout=0);
/** return an (accepted) IOSocket ready for I/O
*
*/
virtual const IOSocket accept(const struct timespec* timeout = 0);
/** connect to a server socket
*
*/
virtual void connect(const sockaddr* serv_addr);
/** connect to a server socket
*
*/
virtual void connect(const sockaddr* serv_addr);
/** dynamically allocate a copy of this object
*
*/
virtual Socket* clone() const;
/** dynamically allocate a copy of this object
*
*/
virtual Socket* clone() const;
/** get a string rep of the object
*
*/
virtual const std::string toString() const;
/** get a string rep of the object
*
*/
virtual const std::string toString() const;
/** set the connection timeout (in ms)
*
*/
virtual void connectionTimeout(const struct ::timespec* timeout) { if (timeout) fConnectionTimeout = *timeout; }
/** set the connection timeout (in ms)
*
*/
virtual void connectionTimeout(const struct ::timespec* timeout)
{
if (timeout) fConnectionTimeout = *timeout;
}
/** set the connection protocol to be synchronous
*
*/
virtual void syncProto(bool use) { fSyncProto = use; }
/** set the connection protocol to be synchronous
*
*/
virtual void syncProto(bool use)
{
fSyncProto = use;
}
const int getConnectionNum() const { return fSocketParms.sd(); }
const int getConnectionNum() const
{
return fSocketParms.sd();
}
/* The caller needs to know when/if the remote closes the connection or sends data.
* Returns 0 on timeout, 1 if there is data to read, 2 if the connection was dropped.
* On error 3 is returned.
*/
static int pollConnection(int connectionNum, long msecs);
/* The caller needs to know when/if the remote closes the connection or sends data.
* Returns 0 on timeout, 1 if there is data to read, 2 if the connection was dropped.
* On error 3 is returned.
*/
static int pollConnection(int connectionNum, long msecs);
/** return the address as a string
*
*/
virtual const std::string addr2String() const;
/** return the address as a string
*
*/
virtual const std::string addr2String() const;
/** compare 2 addresses
*
*/
virtual const bool isSameAddr(const Socket* rhs) const;
/** compare 2 addresses
*
*/
virtual const bool isSameAddr(const Socket* rhs) const;
/** ping an ip address
*
*/
EXPORT static int ping(const std::string& ipaddr, const struct timespec* timeout=0);
/** ping an ip address
*
*/
EXPORT static int ping(const std::string& ipaddr, const struct timespec* timeout = 0);
// Check if we are still connected
virtual bool isConnected() const;
// Check if the socket still has data pending
virtual bool hasData() const;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
protected:
static const int KERR_ERESTARTSYS = 512;
static const int KERR_ERESTARTSYS = 512;
void logIoError(const char* errMsg, int errNum) const;
void logIoError(const char* errMsg, int errNum) const;
/** Empty the stream up to the beginning of the next ByteStream.
*
* Reads until the beginning of the next ByteStream is found.
* @param msecs An optional timeout value.
* @param residual Pass in an array of at least 8 bytes, on return it will contain
* the first bytes of the stream.
* @param reslen On return, it will contain the # of bytes in residual.
* @return true if the next byte in the stream is the beginning of a ByteStream,
* false otherwise.
*/
virtual bool readToMagic(long msecs, bool* isTimeOut, Stats *stats) const;
/** Empty the stream up to the beginning of the next ByteStream.
*
* Reads until the beginning of the next ByteStream is found.
* @param msecs An optional timeout value.
* @param residual Pass in an array of at least 8 bytes, on return it will contain
* the first bytes of the stream.
* @param reslen On return, it will contain the # of bytes in residual.
* @return true if the next byte in the stream is the beginning of a ByteStream,
* false otherwise.
*/
virtual bool readToMagic(long msecs, bool* isTimeOut, Stats* stats) const;
void do_write(const ByteStream &msg, uint32_t magic, Stats *stats = NULL) const;
ssize_t written(int fd, const uint8_t* ptr, size_t nbytes) const;
void do_write(const ByteStream& msg, uint32_t magic, Stats* stats = NULL) const;
ssize_t written(int fd, const uint8_t* ptr, size_t nbytes) const;
SocketParms fSocketParms; /// The socket parms
size_t fBlocksize;
sockaddr_in fSa;
SocketParms fSocketParms; /// The socket parms
size_t fBlocksize;
sockaddr_in fSa;
// how long to wait for a connect() call to complete (in ms)
struct ::timespec fConnectionTimeout;
// how long to wait for a connect() call to complete (in ms)
struct ::timespec fConnectionTimeout;
// use sync proto
bool fSyncProto;
// use sync proto
bool fSyncProto;
/// The buffer used to scan for the ByteStream magic in the stream.
mutable uint32_t fMagicBuffer;
/// The buffer used to scan for the ByteStream magic in the stream.
mutable uint32_t fMagicBuffer;
private:
void doCopy(const InetStreamSocket& rhs);
void doCopy(const InetStreamSocket& rhs);
};
inline const bool InetStreamSocket::isOpen() const { return (fSocketParms.sd() >= 0); }
inline const SocketParms InetStreamSocket::socketParms() const { return fSocketParms; }
inline void InetStreamSocket::socketParms(const SocketParms& socketParms) { fSocketParms = socketParms; }
inline void InetStreamSocket::sa(const sockaddr* sa) { memcpy(&fSa, sa, sizeof(sockaddr_in)); }
inline const bool InetStreamSocket::isOpen() const
{
return (fSocketParms.sd() >= 0);
}
inline const SocketParms InetStreamSocket::socketParms() const
{
return fSocketParms;
}
inline void InetStreamSocket::socketParms(const SocketParms& socketParms)
{
fSocketParms = socketParms;
}
inline void InetStreamSocket::sa(const sockaddr* sa)
{
memcpy(&fSa, sa, sizeof(sockaddr_in));
}
/**
* stream an InetStreamSocket rep to any ostream
*/
inline std::ostream& operator<<(std::ostream& os, const InetStreamSocket& rhs)
{
os << rhs.toString();
return os;
os << rhs.toString();
return os;
}
} //namespace messageqcpp

View File

@ -40,57 +40,58 @@ using namespace std;
#include "iosocket.h"
#undef IOSOCKET_DLLEXPORT
namespace messageqcpp {
namespace messageqcpp
{
IOSocket::IOSocket(Socket* socket) :
fSocket(socket), sockID(0)
fSocket(socket), sockID(0)
{
memset(&fSa, 0, sizeof(fSa));
memset(&fSa, 0, sizeof(fSa));
}
IOSocket::~IOSocket()
{
delete fSocket;
delete fSocket;
}
void IOSocket::doCopy(const IOSocket& rhs)
{
fSocket = rhs.fSocket->clone();
fSa = rhs.fSa;
sockID = rhs.sockID;
fSocket = rhs.fSocket->clone();
fSa = rhs.fSa;
sockID = rhs.sockID;
}
IOSocket::IOSocket(const IOSocket& rhs)
{
doCopy(rhs);
doCopy(rhs);
}
IOSocket& IOSocket::operator=(const IOSocket& rhs)
{
if (this != &rhs)
{
delete fSocket;
doCopy(rhs);
}
if (this != &rhs)
{
delete fSocket;
doCopy(rhs);
}
return *this;
return *this;
}
const string IOSocket::toString() const
{
#ifdef NOSSTREAM
return "IOSocket";
return "IOSocket";
#else
ostringstream oss;
char buf[INET_ADDRSTRLEN];
SocketParms sp = fSocket->socketParms();
const sockaddr_in* sinp = reinterpret_cast<const sockaddr_in*>(&fSa);
oss << "IOSocket: sd: " << sp.sd() <<
ostringstream oss;
char buf[INET_ADDRSTRLEN];
SocketParms sp = fSocket->socketParms();
const sockaddr_in* sinp = reinterpret_cast<const sockaddr_in*>(&fSa);
oss << "IOSocket: sd: " << sp.sd() <<
#ifndef _MSC_VER
" inet: " << inet_ntop(AF_INET, &sinp->sin_addr, buf, INET_ADDRSTRLEN) <<
" inet: " << inet_ntop(AF_INET, &sinp->sin_addr, buf, INET_ADDRSTRLEN) <<
#endif
" port: " << ntohs(sinp->sin_port);
return oss.str();
" port: " << ntohs(sinp->sin_port);
return oss.str();
#endif
}

View File

@ -51,7 +51,8 @@ class MessageQTestSuite;
#define EXPORT
#endif
namespace messageqcpp {
namespace messageqcpp
{
class ServerSocket;
/** a socket capable of I/O
@ -61,165 +62,238 @@ class IOSocket
{
public:
/** ctor
*
*/
EXPORT explicit IOSocket(Socket* socket=0);
/** ctor
*
*/
EXPORT explicit IOSocket(Socket* socket = 0);
/** copy ctor
*
*/
EXPORT IOSocket(const IOSocket& rhs);
/** copy ctor
*
*/
EXPORT IOSocket(const IOSocket& rhs);
/** assign op
*
*/
EXPORT IOSocket& operator=(const IOSocket& rhs);
/** assign op
*
*/
EXPORT IOSocket& operator=(const IOSocket& rhs);
/** dtor
*
*/
EXPORT virtual ~IOSocket();
/** dtor
*
*/
EXPORT virtual ~IOSocket();
/** read a ByteStream from this socket
*
* This socket needs to be connected first. Will throw runtime_error on I/O error. Caller should
* call close() method if exception is thrown.
*/
virtual const SBS read(const struct timespec* timeout=0, bool* isTimeOut = NULL, Stats *stats = NULL) const;
/** read a ByteStream from this socket
*
* This socket needs to be connected first. Will throw runtime_error on I/O error. Caller should
* call close() method if exception is thrown.
*/
virtual const SBS read(const struct timespec* timeout = 0, bool* isTimeOut = NULL, Stats* stats = NULL) const;
/** write a ByteStream to this socket
*
* This socket needs to be connected first. Will throw runtime_error on I/O error. Caller should
* call close() method if exception is thrown.
*/
EXPORT virtual void write(const ByteStream& msg, Stats *stats = NULL) const;
EXPORT virtual void write_raw(const ByteStream& msg, Stats *stats = NULL) const;
EXPORT virtual void write(SBS msg, Stats *stats = NULL) const;
/** access the sockaddr member
*/
inline virtual const sockaddr sa() const;
/** write a ByteStream to this socket
*
* This socket needs to be connected first. Will throw runtime_error on I/O error. Caller should
* call close() method if exception is thrown.
*/
EXPORT virtual void write(const ByteStream& msg, Stats* stats = NULL) const;
EXPORT virtual void write_raw(const ByteStream& msg, Stats* stats = NULL) const;
EXPORT virtual void write(SBS msg, Stats* stats = NULL) const;
/** modify the sockaddr member
*/
inline virtual void sa(const sockaddr* sa);
/** access the sockaddr member
*/
inline virtual const sockaddr sa() const;
/** open the socket
*
*/
inline virtual void open();
/** modify the sockaddr member
*/
inline virtual void sa(const sockaddr* sa);
/** close the socket
*
*/
inline virtual void close();
/** open the socket
*
*/
inline virtual void open();
/** test if the socket is open
*
*/
inline virtual const bool isOpen() const;
/** close the socket
*
*/
inline virtual void close();
/** get the socket params
*
*/
inline virtual const SocketParms socketParms() const;
/** test if the socket is open
*
*/
inline virtual const bool isOpen() const;
/** set the socket params
*
*/
inline virtual void socketParms(const SocketParms& socketParms);
/** get the socket params
*
*/
inline virtual const SocketParms socketParms() const;
/** set the socket implementation
*
* Install a socket implementation that meets the Socket interface
*/
EXPORT virtual void setSocketImpl(Socket* socket);
/** set the socket params
*
*/
inline virtual void socketParms(const SocketParms& socketParms);
/** get a string rep of the IOSocket
*
*/
EXPORT virtual const std::string toString() const;
/** set the socket implementation
*
* Install a socket implementation that meets the Socket interface
*/
EXPORT virtual void setSocketImpl(Socket* socket);
/** syncProto() forwarder for inherited classes
*
*/
EXPORT virtual void syncProto(bool use) { fSocket->syncProto(use); }
/** get a string rep of the IOSocket
*
*/
EXPORT virtual const std::string toString() const;
EXPORT virtual const int getConnectionNum() const;
/** syncProto() forwarder for inherited classes
*
*/
EXPORT virtual void syncProto(bool use)
{
fSocket->syncProto(use);
}
// Debug
EXPORT void setSockID(uint32_t id) {sockID = id;}
EXPORT uint32_t getSockID() {return sockID;}
/*
* allow test suite access to private data for OOB test
*/
/**
* @brief return the address as a string
*/
virtual const std::string addr2String() const { return fSocket->addr2String(); }
EXPORT virtual const int getConnectionNum() const;
/**
* @brief compare 2 addresses
*/
virtual const bool isSameAddr(const IOSocket *rhs) const { return fSocket->isSameAddr(rhs->fSocket); }
/** connect() forwarder for inherited classes
*
*/
virtual void connect(const struct sockaddr* serv_addr) { fSocket->connect(serv_addr); }
// Debug
EXPORT void setSockID(uint32_t id)
{
sockID = id;
}
EXPORT uint32_t getSockID()
{
return sockID;
}
/*
* allow test suite access to private data for OOB test
*/
/**
* @brief return the address as a string
*/
virtual const std::string addr2String() const
{
return fSocket->addr2String();
}
/** connectionTimeout() forwarder for inherited classes
*
*/
virtual void connectionTimeout(const struct timespec* timeout) { fSocket->connectionTimeout(timeout); }
inline virtual bool isConnected() const;
/**
* @brief compare 2 addresses
*/
virtual const bool isSameAddr(const IOSocket* rhs) const
{
return fSocket->isSameAddr(rhs->fSocket);
}
/** connect() forwarder for inherited classes
*
*/
virtual void connect(const struct sockaddr* serv_addr)
{
fSocket->connect(serv_addr);
}
/** connectionTimeout() forwarder for inherited classes
*
*/
virtual void connectionTimeout(const struct timespec* timeout)
{
fSocket->connectionTimeout(timeout);
}
inline virtual bool isConnected() const;
inline virtual bool hasData() const;
friend class ::MessageQTestSuite;
friend class ::MessageQTestSuite;
protected:
private:
void doCopy(const IOSocket& rhs);
void doCopy(const IOSocket& rhs);
Socket* fSocket;
sockaddr fSa;
uint32_t sockID; // For debug purposes
Socket* fSocket;
sockaddr fSa;
uint32_t sockID; // For debug purposes
};
inline const sockaddr IOSocket::sa() const { return fSa; }
inline const sockaddr IOSocket::sa() const
{
return fSa;
}
inline void IOSocket::sa(const sockaddr* sa)
{ fSa = *sa;
if (fSocket)
fSocket->sa( sa ); }
inline void IOSocket::open() { idbassert(fSocket); fSocket->open(); }
{
fSa = *sa;
if (fSocket)
fSocket->sa( sa );
}
inline void IOSocket::open()
{
idbassert(fSocket);
fSocket->open();
}
//RJD: changing close() to simply bail on null fSocket. I'm not really sure what's best here, but this is probably
// better that asserting...
inline void IOSocket::close() { if (fSocket) fSocket->close(); }
inline const bool IOSocket::isOpen() const { return (fSocket && fSocket->isOpen()); }
inline const SBS IOSocket::read(const struct timespec* timeout, bool* isTimeOut, Stats *stats) const
{ idbassert(fSocket); return fSocket->read(timeout, isTimeOut, stats); }
inline void IOSocket::write(const ByteStream& msg, Stats *stats) const { idbassert(fSocket); fSocket->write(msg, stats); }
inline void IOSocket::write_raw(const ByteStream& msg, Stats *stats) const { idbassert(fSocket); fSocket->write_raw(msg, stats); }
inline void IOSocket::write(SBS msg, Stats *stats) const { idbassert(fSocket); fSocket->write(msg, stats); }
inline const SocketParms IOSocket::socketParms() const { idbassert(fSocket); return fSocket->socketParms(); }
inline void IOSocket::socketParms(const SocketParms& socketParms) { idbassert(fSocket); fSocket->socketParms(socketParms); }
inline void IOSocket::setSocketImpl(Socket* socket) { delete fSocket; fSocket = socket; }
inline const int IOSocket::getConnectionNum() const { return fSocket->getConnectionNum(); }
inline bool IOSocket::isConnected() const { return fSocket->isConnected(); }
inline bool IOSocket::hasData() const { return fSocket->hasData(); }
inline void IOSocket::close()
{
if (fSocket) fSocket->close();
}
inline const bool IOSocket::isOpen() const
{
return (fSocket && fSocket->isOpen());
}
inline const SBS IOSocket::read(const struct timespec* timeout, bool* isTimeOut, Stats* stats) const
{
idbassert(fSocket);
return fSocket->read(timeout, isTimeOut, stats);
}
inline void IOSocket::write(const ByteStream& msg, Stats* stats) const
{
idbassert(fSocket);
fSocket->write(msg, stats);
}
inline void IOSocket::write_raw(const ByteStream& msg, Stats* stats) const
{
idbassert(fSocket);
fSocket->write_raw(msg, stats);
}
inline void IOSocket::write(SBS msg, Stats* stats) const
{
idbassert(fSocket);
fSocket->write(msg, stats);
}
inline const SocketParms IOSocket::socketParms() const
{
idbassert(fSocket);
return fSocket->socketParms();
}
inline void IOSocket::socketParms(const SocketParms& socketParms)
{
idbassert(fSocket);
fSocket->socketParms(socketParms);
}
inline void IOSocket::setSocketImpl(Socket* socket)
{
delete fSocket;
fSocket = socket;
}
inline const int IOSocket::getConnectionNum() const
{
return fSocket->getConnectionNum();
}
inline bool IOSocket::isConnected() const
{
return fSocket->isConnected();
}
inline bool IOSocket::hasData() const
{
return fSocket->hasData();
}
/**
* stream an IOSocket rep to any ostream
*/
inline std::ostream& operator<<(std::ostream& os, const IOSocket& rhs)
{
os << rhs.toString();
return os;
os << rhs.toString();
return os;
}
} //namespace messageqcpp

View File

@ -52,279 +52,300 @@ using namespace config;
#include "messagequeue.h"
#undef MESSAGEQUEUE_DLLEXPORT
namespace messageqcpp {
namespace messageqcpp
{
void MessageQueueServer::setup(size_t blocksize, int backlog, bool syncProto)
{
string thisEndPortStr;
string thisEndPortStr;
thisEndPortStr = fConfig->getConfig(fThisEnd, "Port");
uint16_t port;
thisEndPortStr = fConfig->getConfig(fThisEnd, "Port");
uint16_t port;
if (thisEndPortStr.length() == 0 || (port = static_cast<uint16_t>(strtol(thisEndPortStr.c_str(), 0, 0))) == 0)
{
string msg = "MessageQueueServer::MessageQueueServer: config error: Invalid/Missing Port "
"attribute for " + fThisEnd;
throw runtime_error(msg);
}
if (thisEndPortStr.length() == 0 || (port = static_cast<uint16_t>(strtol(thisEndPortStr.c_str(), 0, 0))) == 0)
{
string msg = "MessageQueueServer::MessageQueueServer: config error: Invalid/Missing Port "
"attribute for " + fThisEnd;
throw runtime_error(msg);
}
in_addr listenAddr;
listenAddr.s_addr = INADDR_ANY;
string listenAddrStr = fConfig->getConfig(fThisEnd, "ListenAddr");
if (listenAddrStr.length() > 0)
{
struct in_addr la;
if (inet_aton(listenAddrStr.c_str(), &la) != 0)
listenAddr = la;
}
in_addr listenAddr;
listenAddr.s_addr = INADDR_ANY;
string listenAddrStr = fConfig->getConfig(fThisEnd, "ListenAddr");
memset(&fServ_addr, 0, sizeof(fServ_addr));
sockaddr_in* sinp = reinterpret_cast<sockaddr_in*>(&fServ_addr);
sinp->sin_family = AF_INET;
sinp->sin_addr.s_addr = listenAddr.s_addr;
sinp->sin_port = htons(port);
if (listenAddrStr.length() > 0)
{
struct in_addr la;
if (inet_aton(listenAddrStr.c_str(), &la) != 0)
listenAddr = la;
}
memset(&fServ_addr, 0, sizeof(fServ_addr));
sockaddr_in* sinp = reinterpret_cast<sockaddr_in*>(&fServ_addr);
sinp->sin_family = AF_INET;
sinp->sin_addr.s_addr = listenAddr.s_addr;
sinp->sin_port = htons(port);
#ifdef SKIP_IDB_COMPRESSION
fListenSock.setSocketImpl(new InetStreamSocket(blocksize));
fListenSock.setSocketImpl(new InetStreamSocket(blocksize));
#else
fListenSock.setSocketImpl(new CompressedInetStreamSocket());
fListenSock.setSocketImpl(new CompressedInetStreamSocket());
#endif
fListenSock.syncProto(syncProto);
fListenSock.open();
fListenSock.bind(&fServ_addr);
fListenSock.listen(backlog);
fListenSock.syncProto(syncProto);
fListenSock.open();
fListenSock.bind(&fServ_addr);
fListenSock.listen(backlog);
#ifdef SKIP_IDB_COMPRESSION
fClientSock.setSocketImpl(new InetStreamSocket(blocksize));
fClientSock.setSocketImpl(new InetStreamSocket(blocksize));
#else
fClientSock.setSocketImpl(new CompressedInetStreamSocket());
fClientSock.setSocketImpl(new CompressedInetStreamSocket());
#endif
fClientSock.syncProto(syncProto);
fClientSock.syncProto(syncProto);
}
MessageQueueServer::MessageQueueServer(const string& thisEnd, const string& config,
size_t blocksize, int backlog, bool syncProto) :
fThisEnd(thisEnd),
fConfig(Config::makeConfig(config)),
fLogger(31)
size_t blocksize, int backlog, bool syncProto) :
fThisEnd(thisEnd),
fConfig(Config::makeConfig(config)),
fLogger(31)
{
setup(blocksize, backlog, syncProto);
setup(blocksize, backlog, syncProto);
}
MessageQueueServer::MessageQueueServer(const string& thisEnd, Config* config,
size_t blocksize, int backlog, bool syncProto) :
fThisEnd(thisEnd),
fConfig(config),
fLogger(31)
size_t blocksize, int backlog, bool syncProto) :
fThisEnd(thisEnd),
fConfig(config),
fLogger(31)
{
if (fConfig == 0)
fConfig = Config::makeConfig();
if (fConfig == 0)
fConfig = Config::makeConfig();
setup(blocksize, backlog, syncProto);
setup(blocksize, backlog, syncProto);
}
MessageQueueServer::~MessageQueueServer()
{
fClientSock.close();
fListenSock.close();
fClientSock.close();
fListenSock.close();
}
const IOSocket MessageQueueServer::accept(const struct timespec* timeout) const
{
return fListenSock.accept(timeout);
return fListenSock.accept(timeout);
}
void MessageQueueServer::syncProto(bool use)
{
fListenSock.syncProto(use);
fClientSock.syncProto(use);
fListenSock.syncProto(use);
fClientSock.syncProto(use);
}
MessageQueueClient::~MessageQueueClient()
{
fClientSock.close();
fClientSock.close();
}
void MessageQueueClient::shutdown()
{
fClientSock.close();
fClientSock.close();
}
void MessageQueueClient::setup(bool syncProto)
{
string otherEndIPStr;
string otherEndPortStr;
uint16_t port;
string otherEndIPStr;
string otherEndPortStr;
uint16_t port;
otherEndIPStr = fConfig->getConfig(fOtherEnd, "IPAddr");
otherEndPortStr = fConfig->getConfig(fOtherEnd, "Port");
otherEndIPStr = fConfig->getConfig(fOtherEnd, "IPAddr");
otherEndPortStr = fConfig->getConfig(fOtherEnd, "Port");
if (otherEndIPStr.length() == 0) otherEndIPStr = "127.0.0.1";
if (otherEndIPStr.length() == 0) otherEndIPStr = "127.0.0.1";
if (otherEndPortStr.length() == 0 || (port = static_cast<uint16_t>(strtol(otherEndPortStr.c_str(), 0, 0))) == 0)
{
string msg = "MessageQueueClient::MessageQueueClient: config error: Invalid/Missing Port attribute";
throw runtime_error(msg);
}
if (otherEndPortStr.length() == 0 || (port = static_cast<uint16_t>(strtol(otherEndPortStr.c_str(), 0, 0))) == 0)
{
string msg = "MessageQueueClient::MessageQueueClient: config error: Invalid/Missing Port attribute";
throw runtime_error(msg);
}
memset(&fServ_addr, 0, sizeof(fServ_addr));
sockaddr_in* sinp = reinterpret_cast<sockaddr_in*>(&fServ_addr);
sinp->sin_family = AF_INET;
sinp->sin_port = htons(port);
sinp->sin_addr.s_addr = inet_addr(otherEndIPStr.c_str());
memset(&fServ_addr, 0, sizeof(fServ_addr));
sockaddr_in* sinp = reinterpret_cast<sockaddr_in*>(&fServ_addr);
sinp->sin_family = AF_INET;
sinp->sin_port = htons(port);
sinp->sin_addr.s_addr = inet_addr(otherEndIPStr.c_str());
#ifdef SKIP_IDB_COMPRESSION
fClientSock.setSocketImpl(new InetStreamSocket());
fClientSock.setSocketImpl(new InetStreamSocket());
#else
fClientSock.setSocketImpl(new CompressedInetStreamSocket());
fClientSock.setSocketImpl(new CompressedInetStreamSocket());
#endif
fClientSock.syncProto(syncProto);
fClientSock.sa(&fServ_addr);
fClientSock.syncProto(syncProto);
fClientSock.sa(&fServ_addr);
}
MessageQueueClient::MessageQueueClient(const string& otherEnd, const string& config, bool syncProto) :
fOtherEnd(otherEnd), fConfig(Config::makeConfig(config)), fLogger(31), fIsAvailable(true)
fOtherEnd(otherEnd), fConfig(Config::makeConfig(config)), fLogger(31), fIsAvailable(true)
{
setup(syncProto);
setup(syncProto);
}
MessageQueueClient::MessageQueueClient(const string& otherEnd, Config* config, bool syncProto) :
fOtherEnd(otherEnd), fConfig(config), fLogger(31), fIsAvailable(true)
fOtherEnd(otherEnd), fConfig(config), fLogger(31), fIsAvailable(true)
{
if (fConfig == 0)
fConfig = Config::makeConfig();
if (fConfig == 0)
fConfig = Config::makeConfig();
setup(syncProto);
setup(syncProto);
}
MessageQueueClient::MessageQueueClient(const string& ip, uint16_t port, bool syncProto) :
fLogger(31), fIsAvailable(true)
fLogger(31), fIsAvailable(true)
{
memset(&fServ_addr, 0, sizeof(fServ_addr));
sockaddr_in* sinp = reinterpret_cast<sockaddr_in*>(&fServ_addr);
sinp->sin_family = AF_INET;
sinp->sin_port = htons(port);
sinp->sin_addr.s_addr = inet_addr(ip.c_str());
memset(&fServ_addr, 0, sizeof(fServ_addr));
sockaddr_in* sinp = reinterpret_cast<sockaddr_in*>(&fServ_addr);
sinp->sin_family = AF_INET;
sinp->sin_port = htons(port);
sinp->sin_addr.s_addr = inet_addr(ip.c_str());
#ifdef SKIP_IDB_COMPRESSION
fClientSock.setSocketImpl(new InetStreamSocket());
fClientSock.setSocketImpl(new InetStreamSocket());
#else
fClientSock.setSocketImpl(new CompressedInetStreamSocket());
fClientSock.setSocketImpl(new CompressedInetStreamSocket());
#endif
fClientSock.syncProto(syncProto);
fClientSock.sa(&fServ_addr);
fClientSock.syncProto(syncProto);
fClientSock.sa(&fServ_addr);
}
const SBS MessageQueueClient::read(const struct timespec* timeout, bool* isTimeOut, Stats *stats) const
const SBS MessageQueueClient::read(const struct timespec* timeout, bool* isTimeOut, Stats* stats) const
{
if (!fClientSock.isOpen())
{
fClientSock.open();
try {
fClientSock.connect(&fServ_addr);
}
catch (...) {
fClientSock.close();
throw;
}
}
if (!fClientSock.isOpen())
{
fClientSock.open();
SBS res;
try
{
res = fClientSock.read(timeout, isTimeOut, stats);
}
catch (runtime_error& re)
{
// This is an I/O error from IOSocket::read()
try
{
fClientSock.connect(&fServ_addr);
}
catch (...)
{
fClientSock.close();
throw;
}
}
SBS res;
try
{
res = fClientSock.read(timeout, isTimeOut, stats);
}
catch (runtime_error& re)
{
// This is an I/O error from IOSocket::read()
// cerr << "MessageQueueClient::read: close socket for " << re.what() << endl;
logging::Message::Args args;
logging::LoggingID li(31);
args.add("Client read close socket for");
args.add(re.what());
fLogger.logMessage(logging::LOG_TYPE_WARNING, logging::M0000, args, li);
fClientSock.close();
throw;
}
catch (SocketClosed &e) {
logging::Message::Args args;
logging::LoggingID li(31);
args.add("Client read close socket for");
args.add(re.what());
fLogger.logMessage(logging::LOG_TYPE_WARNING, logging::M0000, args, li);
fClientSock.close();
throw;
}
catch (SocketClosed& e)
{
// cerr << "MessageQueueClient::read: close socket for " << e.what() << endl;
logging::Message::Args args;
logging::LoggingID li(31);
args.add("Client read close socket for");
args.add(e.what());
fLogger.logMessage(logging::LOG_TYPE_WARNING, logging::M0000, args, li);
fClientSock.close();
throw;
}
return res;
logging::Message::Args args;
logging::LoggingID li(31);
args.add("Client read close socket for");
args.add(e.what());
fLogger.logMessage(logging::LOG_TYPE_WARNING, logging::M0000, args, li);
fClientSock.close();
throw;
}
return res;
}
void MessageQueueClient::write(const ByteStream& msg, const struct timespec* timeout, Stats *stats) const
void MessageQueueClient::write(const ByteStream& msg, const struct timespec* timeout, Stats* stats) const
{
if (!fClientSock.isOpen())
{
fClientSock.open();
try {
fClientSock.connectionTimeout(timeout);
fClientSock.connect(&fServ_addr);
}
catch(...) {
fClientSock.close();
throw;
}
}
if (!fClientSock.isOpen())
{
fClientSock.open();
try {
fClientSock.write(msg, stats);
}
catch (runtime_error &e) {
try
{
ostringstream oss;
oss << "MessageQueueClient::write: error writing " << msg.length() << " bytes to "
<< fClientSock << ". Socket error was " << e.what() << endl;
try
{
fClientSock.connectionTimeout(timeout);
fClientSock.connect(&fServ_addr);
}
catch (...)
{
fClientSock.close();
throw;
}
}
try
{
fClientSock.write(msg, stats);
}
catch (runtime_error& e)
{
try
{
ostringstream oss;
oss << "MessageQueueClient::write: error writing " << msg.length() << " bytes to "
<< fClientSock << ". Socket error was " << e.what() << endl;
// cerr << oss.str() << endl;
logging::Message::Args args;
logging::LoggingID li(31);
args.add(oss.str());
fLogger.logMessage(logging::LOG_TYPE_WARNING, logging::M0000, args, li);
}
catch (...)
{
}
fClientSock.close();
throw;
}
logging::Message::Args args;
logging::LoggingID li(31);
args.add(oss.str());
fLogger.logMessage(logging::LOG_TYPE_WARNING, logging::M0000, args, li);
}
catch (...)
{
}
fClientSock.close();
throw;
}
}
bool MessageQueueClient::connect() const
{
if (!fClientSock.isOpen())
{
fClientSock.open();
if (!fClientSock.isOpen())
{
fClientSock.open();
try {
fClientSock.connect(&fServ_addr);
}
catch (runtime_error& re) {
string what = re.what();
if (what.find("Connection refused") != string::npos)
{
try {
fClientSock.close();
}
catch (...) {
}
}
else
throw;
}
catch (...) {
throw;
}
}
try
{
fClientSock.connect(&fServ_addr);
}
catch (runtime_error& re)
{
string what = re.what();
return fClientSock.isOpen();
if (what.find("Connection refused") != string::npos)
{
try
{
fClientSock.close();
}
catch (...)
{
}
}
else
throw;
}
catch (...)
{
throw;
}
}
return fClientSock.isOpen();
}
}//namespace messageqcpp

View File

@ -52,7 +52,8 @@ class MessageQTestSuite;
#define EXPORT
#endif
namespace messageqcpp {
namespace messageqcpp
{
/**
* @brief a message queue server
@ -75,75 +76,75 @@ namespace messageqcpp {
class MessageQueueServer
{
public:
/**
* @brief construct a server queue for thisEnd
*
* construct a server queue for thisEnd. Optionally specify a Config object to use.
*/
EXPORT explicit MessageQueueServer(const std::string& thisEnd, config::Config* config=0,
size_t blocksize=ByteStream::BlockSize, int backlog=5, bool syncProto=true);
/**
* @brief construct a server queue for thisEnd
*
* construct a server queue for thisEnd, specifying the name of a config file to use.
*/
EXPORT MessageQueueServer(const std::string& thisEnd, const std::string& config,
size_t blocksize=ByteStream::BlockSize, int backlog=5, bool syncProto=true);
/**
* @brief destructor
*/
EXPORT ~MessageQueueServer();
//
/**
* @brief wait for a connection and return an IOSocket
*
* This method can be used by a main thread to wait for an incoming connection. The IOSocket
* that is returned can be passed to a thread to handle the socket connection. The main thread
* is then free to wait again for another connection. The IOSocket is already open and ready for
* read() and/or write(). The caller is responsible for calling close() when it is done.
*/
EXPORT const IOSocket accept(const struct timespec* timeout=0) const;
/**
* @brief get a mutable pointer to the client IOSocket
*/
inline IOSocket& clientSock() const;
/**
* @brief set the sync proto
*/
EXPORT void syncProto(bool use);
/**
* @brief construct a server queue for thisEnd
*
* construct a server queue for thisEnd. Optionally specify a Config object to use.
*/
EXPORT explicit MessageQueueServer(const std::string& thisEnd, config::Config* config = 0,
size_t blocksize = ByteStream::BlockSize, int backlog = 5, bool syncProto = true);
/**
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
* @brief construct a server queue for thisEnd
*
* construct a server queue for thisEnd, specifying the name of a config file to use.
*/
EXPORT MessageQueueServer(const std::string& thisEnd, const std::string& config,
size_t blocksize = ByteStream::BlockSize, int backlog = 5, bool syncProto = true);
/**
* @brief destructor
*/
EXPORT ~MessageQueueServer();
//
/**
* @brief wait for a connection and return an IOSocket
*
* This method can be used by a main thread to wait for an incoming connection. The IOSocket
* that is returned can be passed to a thread to handle the socket connection. The main thread
* is then free to wait again for another connection. The IOSocket is already open and ready for
* read() and/or write(). The caller is responsible for calling close() when it is done.
*/
EXPORT const IOSocket accept(const struct timespec* timeout = 0) const;
/**
* @brief get a mutable pointer to the client IOSocket
*/
inline IOSocket& clientSock() const;
/**
* @brief set the sync proto
*/
EXPORT void syncProto(bool use);
/**
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
private:
/** copy ctor
*
*/
MessageQueueServer(const MessageQueueServer& rhs);
/** copy ctor
*
*/
MessageQueueServer(const MessageQueueServer& rhs);
/** assign op
*
*/
MessageQueueServer& operator=(const MessageQueueServer& rhs);
/** assign op
*
*/
MessageQueueServer& operator=(const MessageQueueServer& rhs);
/** ctor helper
*
*/
void setup(size_t blocksize, int backlog, bool syncProto);
/** ctor helper
*
*/
void setup(size_t blocksize, int backlog, bool syncProto);
std::string fThisEnd; /// the process name for this process
struct sockaddr fServ_addr; /// the addr of the server (may be this process)
config::Config* fConfig; /// config file has the IP addrs and port numbers
mutable ServerSocket fListenSock; /// the socket the server listens on for new connections
mutable IOSocket fClientSock; /// the socket connected to a client
std::string fThisEnd; /// the process name for this process
struct sockaddr fServ_addr; /// the addr of the server (may be this process)
config::Config* fConfig; /// config file has the IP addrs and port numbers
mutable ServerSocket fListenSock; /// the socket the server listens on for new connections
mutable IOSocket fClientSock; /// the socket connected to a client
mutable logging::Logger fLogger;
mutable logging::Logger fLogger;
};
/**
@ -163,132 +164,167 @@ private:
class MessageQueueClient
{
public:
/**
* @brief construct a queue to otherEnd
*
* construct a queue from this process to otherEnd. Optionally specify a Config object to use.
*/
EXPORT explicit MessageQueueClient(const std::string& otherEnd, config::Config* config=0, bool syncProto=true);
/**
* @brief construct a queue to otherEnd
*
* construct a queue from this process to otherEnd. Optionally specify a Config object to use.
*/
EXPORT explicit MessageQueueClient(const std::string& otherEnd, config::Config* config = 0, bool syncProto = true);
/**
* @brief construct a queue to otherEnd
*
* construct a queue from this process to otherEnd, specifying the name of a config file to use.
*/
EXPORT explicit MessageQueueClient(const std::string& otherEnd, const std::string& config, bool syncProto=true);
/**
* @brief construct a queue to otherEnd
*
* construct a queue from this process to otherEnd, specifying the name of a config file to use.
*/
EXPORT explicit MessageQueueClient(const std::string& otherEnd, const std::string& config, bool syncProto = true);
/**
* @brief construct a queue to otherEnd
*
* construct a queue from this process to otherEnd on the given IP and Port.
*/
EXPORT explicit MessageQueueClient(const std::string& ip, uint16_t port, bool syncProto=true);
/**
* @brief construct a queue to otherEnd
*
* construct a queue from this process to otherEnd on the given IP and Port.
*/
EXPORT explicit MessageQueueClient(const std::string& ip, uint16_t port, bool syncProto = true);
/**
* @brief destructor
*
* calls shutdown() method.
*/
EXPORT ~MessageQueueClient();
/**
* @brief destructor
*
* calls shutdown() method.
*/
EXPORT ~MessageQueueClient();
/**
* @brief read a message from the queue
*
* wait for and return a message from otherEnd. The deafult timeout waits forever. Note that
* eventhough struct timespec has nanosecond resolution, this method only has milisecond resolution.
*/
EXPORT const SBS read(const struct timespec* timeout=0, bool* isTimeOut = NULL, Stats *stats = NULL) const;
/**
* @brief read a message from the queue
*
* wait for and return a message from otherEnd. The deafult timeout waits forever. Note that
* eventhough struct timespec has nanosecond resolution, this method only has milisecond resolution.
*/
EXPORT const SBS read(const struct timespec* timeout = 0, bool* isTimeOut = NULL, Stats* stats = NULL) const;
/**
* @brief write a message to the queue
*
* write a message to otherEnd. If the socket is not open, the timeout parm (in ms) will be used
* to establish a sync connection w/ the server
*/
EXPORT void write(const ByteStream& msg, const struct timespec* timeout=0, Stats *stats = NULL) const;
/**
* @brief write a message to the queue
*
* write a message to otherEnd. If the socket is not open, the timeout parm (in ms) will be used
* to establish a sync connection w/ the server
*/
EXPORT void write(const ByteStream& msg, const struct timespec* timeout = 0, Stats* stats = NULL) const;
/**
* @brief shutdown the connection to the server
*
* indicate to the class that the user is done with the socket
* and the other class methods won't be used.
*/
EXPORT void shutdown();
/**
* @brief shutdown the connection to the server
*
* indicate to the class that the user is done with the socket
* and the other class methods won't be used.
*/
EXPORT void shutdown();
/**
* @brief connect to the server. Returns true if connection was successful.
*
* read() and write() automatically connect, but this method can be used to verify a server is listening
* before that.
*/
EXPORT bool connect() const;
/**
* @brief accessors and mutators
*/
EXPORT const sockaddr serv_addr() const { return fServ_addr; }
EXPORT const std::string otherEnd() const { return fOtherEnd; }
EXPORT const bool isAvailable() const { return fIsAvailable; }
EXPORT void isAvailable (const bool isAvailable) { fIsAvailable = isAvailable; }
EXPORT const std::string moduleName() const {return fModuleName;}
EXPORT void moduleName(const std::string& moduleName) {fModuleName = moduleName;}
/**
* @brief connect to the server. Returns true if connection was successful.
*
* read() and write() automatically connect, but this method can be used to verify a server is listening
* before that.
*/
EXPORT bool connect() const;
/**
* @brief set the sync proto
*/
inline void syncProto(bool use);
/**
* @brief accessors and mutators
*/
EXPORT const sockaddr serv_addr() const
{
return fServ_addr;
}
EXPORT const std::string otherEnd() const
{
return fOtherEnd;
}
EXPORT const bool isAvailable() const
{
return fIsAvailable;
}
EXPORT void isAvailable (const bool isAvailable)
{
fIsAvailable = isAvailable;
}
EXPORT const std::string moduleName() const
{
return fModuleName;
}
EXPORT void moduleName(const std::string& moduleName)
{
fModuleName = moduleName;
}
/**
* @brief return the address as a string
*/
inline const std::string addr2String() const;
/**
* @brief set the sync proto
*/
inline void syncProto(bool use);
/**
* @brief compare the addresses of 2 MessageQueueClient
*/
inline const bool isSameAddr(const MessageQueueClient& rhs) const;
/**
* @brief return the address as a string
*/
inline const std::string addr2String() const;
bool isConnected() { return fClientSock.isConnected(); }
bool hasData() { return fClientSock.hasData(); }
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
/**
* @brief compare the addresses of 2 MessageQueueClient
*/
inline const bool isSameAddr(const MessageQueueClient& rhs) const;
bool isConnected()
{
return fClientSock.isConnected();
}
bool hasData()
{
return fClientSock.hasData();
}
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
private:
/** copy ctor
*
*/
MessageQueueClient(const MessageQueueClient& rhs);
/** copy ctor
*
*/
MessageQueueClient(const MessageQueueClient& rhs);
/** assign op
*
*/
MessageQueueClient& operator=(const MessageQueueClient& rhs);
/** assign op
*
*/
MessageQueueClient& operator=(const MessageQueueClient& rhs);
/** ctor helper
*
*/
void setup(bool syncProto);
/** ctor helper
*
*/
void setup(bool syncProto);
std::string fOtherEnd; /// the process name for this process
struct sockaddr fServ_addr; /// the addr of the server (may be this process)
config::Config* fConfig; /// config file has the IP addrs and port numbers
mutable IOSocket fClientSock; /// the socket to communicate with the server
mutable logging::Logger fLogger;
bool fIsAvailable;
std::string fModuleName;
std::string fOtherEnd; /// the process name for this process
struct sockaddr fServ_addr; /// the addr of the server (may be this process)
config::Config* fConfig; /// config file has the IP addrs and port numbers
mutable IOSocket fClientSock; /// the socket to communicate with the server
mutable logging::Logger fLogger;
bool fIsAvailable;
std::string fModuleName;
};
inline IOSocket& MessageQueueServer::clientSock() const { return fClientSock; }
inline const std::string MessageQueueClient::addr2String() const { return fClientSock.addr2String(); }
inline IOSocket& MessageQueueServer::clientSock() const
{
return fClientSock;
}
inline const std::string MessageQueueClient::addr2String() const
{
return fClientSock.addr2String();
}
inline const bool MessageQueueClient::isSameAddr(const MessageQueueClient& rhs) const
{ return fClientSock.isSameAddr(&rhs.fClientSock); }
inline void MessageQueueClient::syncProto(bool use) { fClientSock.syncProto(use); }
{
return fClientSock.isSameAddr(&rhs.fClientSock);
}
inline void MessageQueueClient::syncProto(bool use)
{
fClientSock.syncProto(use);
}
}
}
#undef EXPORT

View File

@ -22,7 +22,8 @@
#include "messagequeuepool.h"
#include "messagequeue.h"
namespace messageqcpp {
namespace messageqcpp
{
boost::mutex queueMutex;
// Make linker happy
@ -36,24 +37,24 @@ static uint64_t TimeSpecToSeconds(struct timespec* ts)
return (uint64_t)ts->tv_sec + (uint64_t)ts->tv_nsec / 1000000000;
}
MessageQueueClient *MessageQueueClientPool::getInstance(const std::string &ip, uint64_t port)
MessageQueueClient* MessageQueueClientPool::getInstance(const std::string& ip, uint64_t port)
{
boost::mutex::scoped_lock lock(queueMutex);
std::ostringstream oss;
oss << ip << "_" << port;
std::string searchString = oss.str();
MessageQueueClient *returnClient = MessageQueueClientPool::findInPool(searchString);
MessageQueueClient* returnClient = MessageQueueClientPool::findInPool(searchString);
// We found one, return it
if (returnClient != NULL)
{
return returnClient;
}
// We didn't find one, create new one
ClientObject *newClientObject = new ClientObject();
ClientObject* newClientObject = new ClientObject();
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint64_t nowSeconds = TimeSpecToSeconds(&now);
@ -65,20 +66,20 @@ MessageQueueClient *MessageQueueClientPool::getInstance(const std::string &ip, u
return newClientObject->client;
}
MessageQueueClient *MessageQueueClientPool::getInstance(const std::string &module)
MessageQueueClient* MessageQueueClientPool::getInstance(const std::string& module)
{
boost::mutex::scoped_lock lock(queueMutex);
MessageQueueClient *returnClient = MessageQueueClientPool::findInPool(module);
MessageQueueClient* returnClient = MessageQueueClientPool::findInPool(module);
// We found one, return it
if (returnClient != NULL)
{
return returnClient;
}
// We didn't find one, create new one
ClientObject *newClientObject = new ClientObject();
ClientObject* newClientObject = new ClientObject();
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint64_t nowSeconds = TimeSpecToSeconds(&now);
@ -90,21 +91,21 @@ MessageQueueClient *MessageQueueClientPool::getInstance(const std::string &modul
return newClientObject->client;
}
MessageQueueClient *MessageQueueClientPool::findInPool(const std::string &search)
MessageQueueClient* MessageQueueClientPool::findInPool(const std::string& search)
{
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint64_t nowSeconds = TimeSpecToSeconds(&now);
MessageQueueClient *returnClient = NULL;
std::multimap<std::string,ClientObject*>::iterator it=clientMap.begin();
MessageQueueClient* returnClient = NULL;
std::multimap<std::string, ClientObject*>::iterator it = clientMap.begin();
// Scan pool
while (it!=clientMap.end())
while (it != clientMap.end())
{
ClientObject *clientObject = it->second;
ClientObject* clientObject = it->second;
uint64_t elapsedTime = nowSeconds - clientObject->lastUsed;
// If connection hasn't been used for MAX_IDLE_TIME we probably don't need it so drop it
// Don't drop in use connections that have been in use a long time
if ((elapsedTime >= MAX_IDLE_TIME) && (!clientObject->inUse))
@ -112,30 +113,30 @@ MessageQueueClient *MessageQueueClientPool::findInPool(const std::string &search
delete clientObject->client;
delete clientObject;
// Do this so we don't invalidate current interator
std::multimap<std::string,ClientObject*>::iterator toDelete = it;
std::multimap<std::string, ClientObject*>::iterator toDelete = it;
it++;
clientMap.erase(toDelete);
continue;
}
if (!clientObject->inUse)
{
MessageQueueClient *client = clientObject->client;
MessageQueueClient* client = clientObject->client;
// If the unused socket isn't connected or has data pending read, destroy it
if (!client->isConnected() || client->hasData())
{
delete client;
delete clientObject;
// Do this so we don't invalidate current interator
std::multimap<std::string,ClientObject*>::iterator toDelete = it;
std::multimap<std::string, ClientObject*>::iterator toDelete = it;
it++;
clientMap.erase(toDelete);
continue;
}
}
// If connection matches store it for later, but keep scanning the pool for more timeout prunes
if (it->first.compare(search) == 0)
{
@ -146,23 +147,25 @@ MessageQueueClient *MessageQueueClientPool::findInPool(const std::string &search
return returnClient;
}
}
it++;
}
return NULL;
}
void MessageQueueClientPool::releaseInstance(MessageQueueClient * client)
void MessageQueueClientPool::releaseInstance(MessageQueueClient* client)
{
// Scan pool for pointer and release
// Set the last used and mark as not in use
if (client == NULL)
return;
boost::mutex::scoped_lock lock(queueMutex);
std::multimap<std::string,ClientObject*>::iterator it=clientMap.begin();
while (it!=clientMap.end())
std::multimap<std::string, ClientObject*>::iterator it = clientMap.begin();
while (it != clientMap.end())
{
if (it->second->client == client)
{
@ -173,23 +176,24 @@ void MessageQueueClientPool::releaseInstance(MessageQueueClient * client)
it->second->lastUsed = nowSeconds;
return;
}
it++;
}
}
// WriteEngine needs this as it forces connections closed and can't reuse. Also good for connection errors
void MessageQueueClientPool::deleteInstance(MessageQueueClient * client)
void MessageQueueClientPool::deleteInstance(MessageQueueClient* client)
{
// Scan pool for pointer and delete
// Set the last used and mark as not in use
if (client == NULL)
return;
boost::mutex::scoped_lock lock(queueMutex);
std::multimap<std::string,ClientObject*>::iterator it=clientMap.begin();
while (it!=clientMap.end())
std::multimap<std::string, ClientObject*>::iterator it = clientMap.begin();
while (it != clientMap.end())
{
if (it->second->client == client)
{
@ -198,8 +202,9 @@ void MessageQueueClientPool::deleteInstance(MessageQueueClient * client)
clientMap.erase(it);
return;
}
it++;
}
}
}

View File

@ -21,15 +21,16 @@
#include <map>
#include "messagequeue.h"
namespace messageqcpp {
namespace messageqcpp
{
struct ClientObject
{
MessageQueueClient *client;
MessageQueueClient* client;
uint64_t lastUsed;
bool inUse;
ClientObject() :
client(NULL),
lastUsed(0),
@ -39,18 +40,18 @@ struct ClientObject
class MessageQueueClientPool
{
public:
static MessageQueueClient *getInstance(const std::string &module);
static MessageQueueClient *getInstance(const std::string &ip, uint64_t port);
static void releaseInstance(MessageQueueClient * client);
static void deleteInstance(MessageQueueClient * client);
static MessageQueueClient *findInPool(const std::string &search);
private:
MessageQueueClientPool() { };
~MessageQueueClientPool() { };
static std::multimap<std::string, ClientObject*> clientMap;
public:
static MessageQueueClient* getInstance(const std::string& module);
static MessageQueueClient* getInstance(const std::string& ip, uint64_t port);
static void releaseInstance(MessageQueueClient* client);
static void deleteInstance(MessageQueueClient* client);
static MessageQueueClient* findInPool(const std::string& search);
private:
MessageQueueClientPool() { };
~MessageQueueClientPool() { };
static std::multimap<std::string, ClientObject*> clientMap;
};
}

View File

@ -20,38 +20,40 @@
*
*****************************************************************************/
/** @file
/** @file
* class XXX interface
*/
#ifndef _SERIALIZEABLE_H_
#define _SERIALIZEABLE_H_
namespace messageqcpp {
namespace messageqcpp
{
class ByteStream;
/** This is an abstract class that defines the interface ByteStream will
use to serialize and deserialize your class.
use to serialize and deserialize your class.
To serialize an object, do 'ByteStream << object'
To deserialize an object, instantiate one of its type and do 'ByteStream >> object'
*/
class Serializeable {
class Serializeable
{
public:
/** dtor
*
*/
virtual ~Serializeable() { };
/** serialize interface
*
*/
virtual void serialize(ByteStream&) const = 0;
/** deserialize interface
*
*/
virtual void deserialize(ByteStream&) = 0;
/** dtor
*
*/
virtual ~Serializeable() { };
/** serialize interface
*
*/
virtual void serialize(ByteStream&) const = 0;
/** deserialize interface
*
*/
virtual void deserialize(ByteStream&) = 0;
};
}

View File

@ -38,7 +38,8 @@ class MessageQTestSuite;
#include "socket.h"
#include "iosocket.h"
namespace messageqcpp {
namespace messageqcpp
{
class SocketParms;
/** a class capable of acting as a server listen socket
@ -48,91 +49,125 @@ class ServerSocket
{
public:
/** ctor
*
*/
explicit ServerSocket(Socket* socket=0) : fSocket(socket) {}
/** ctor
*
*/
explicit ServerSocket(Socket* socket = 0) : fSocket(socket) {}
/** dtor
*
*/
virtual ~ServerSocket() { delete fSocket; }
/** dtor
*
*/
virtual ~ServerSocket()
{
delete fSocket;
}
/** bind to an port
*
* bind this ServerSocket to the address/port specified in serv_addr
*/
inline virtual void bind(const struct sockaddr* serv_addr);
/** bind to an port
*
* bind this ServerSocket to the address/port specified in serv_addr
*/
inline virtual void bind(const struct sockaddr* serv_addr);
/** setup to listen for incoming connections
*
*/
inline virtual void listen(int backlog=5);
/** setup to listen for incoming connections
*
*/
inline virtual void listen(int backlog = 5);
/** accept an incoming connection
*
* accepts a new incoming connection and returns an IOSocket to communicate over
*/
inline virtual const IOSocket accept(const struct timespec* timeout=0);
/** accept an incoming connection
*
* accepts a new incoming connection and returns an IOSocket to communicate over
*/
inline virtual const IOSocket accept(const struct timespec* timeout = 0);
/** open the socket
*
*/
inline virtual void open();
/** open the socket
*
*/
inline virtual void open();
/** close the socket
*
*/
inline virtual void close();
/** close the socket
*
*/
inline virtual void close();
/** test if the socket is open
*
*/
inline virtual bool isOpen() const;
/** test if the socket is open
*
*/
inline virtual bool isOpen() const;
/** get the socket params
*
*/
inline virtual const SocketParms socketParms() const;
/** get the socket params
*
*/
inline virtual const SocketParms socketParms() const;
/** set the socket params
*
*/
inline virtual void socketParms(const SocketParms& socketParms);
/** set the socket params
*
*/
inline virtual void socketParms(const SocketParms& socketParms);
/** set the socket implementation
*
* Install a socket implementation that meets the Socket interface
*/
inline virtual void setSocketImpl(Socket* socket);
/** set the socket implementation
*
* Install a socket implementation that meets the Socket interface
*/
inline virtual void setSocketImpl(Socket* socket);
/** set the socket sync proto
*
*/
inline virtual void syncProto(bool use);
/** set the socket sync proto
*
*/
inline virtual void syncProto(bool use);
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
private:
ServerSocket(const ServerSocket& rhs);
ServerSocket& operator=(const ServerSocket& rhs);
ServerSocket(const ServerSocket& rhs);
ServerSocket& operator=(const ServerSocket& rhs);
Socket* fSocket;
Socket* fSocket;
};
inline void ServerSocket::bind(const struct sockaddr* serv_addr) { fSocket->bind(serv_addr); }
inline void ServerSocket::listen(int backlog) { fSocket->listen(backlog); }
inline const IOSocket ServerSocket::accept(const struct timespec* timeout) { return fSocket->accept(timeout); }
inline void ServerSocket::open() { fSocket->open(); }
inline void ServerSocket::close() { fSocket->close(); }
inline bool ServerSocket::isOpen() const { return fSocket->isOpen(); }
inline const SocketParms ServerSocket::socketParms() const { return fSocket->socketParms(); }
inline void ServerSocket::socketParms(const SocketParms& socketParms) { fSocket->socketParms(socketParms); }
inline void ServerSocket::setSocketImpl(Socket* socket) { delete fSocket; fSocket = socket; }
inline void ServerSocket::syncProto(bool use) { fSocket->syncProto(use); }
inline void ServerSocket::bind(const struct sockaddr* serv_addr)
{
fSocket->bind(serv_addr);
}
inline void ServerSocket::listen(int backlog)
{
fSocket->listen(backlog);
}
inline const IOSocket ServerSocket::accept(const struct timespec* timeout)
{
return fSocket->accept(timeout);
}
inline void ServerSocket::open()
{
fSocket->open();
}
inline void ServerSocket::close()
{
fSocket->close();
}
inline bool ServerSocket::isOpen() const
{
return fSocket->isOpen();
}
inline const SocketParms ServerSocket::socketParms() const
{
return fSocket->socketParms();
}
inline void ServerSocket::socketParms(const SocketParms& socketParms)
{
fSocket->socketParms(socketParms);
}
inline void ServerSocket::setSocketImpl(Socket* socket)
{
delete fSocket;
fSocket = socket;
}
inline void ServerSocket::syncProto(bool use)
{
fSocket->syncProto(use);
}
} //namespace messageqcpp

View File

@ -32,27 +32,39 @@
class MessageQTestSuite;
namespace messageqcpp
namespace messageqcpp
{
class IOSocket;
class SocketParms;
// Might want to expand on this / derive from it to include things like uncompressed
// Might want to expand on this / derive from it to include things like uncompressed
// data size, etc...
class Stats
{
public:
Stats() : data_sent(0), data_recvd(0)
{ }
virtual ~Stats() { }
virtual uint64_t dataSent() { return data_sent; }
virtual uint64_t dataRecvd() { return data_recvd; }
virtual void dataSent(uint64_t amt) { data_sent += amt; }
virtual void dataRecvd(uint64_t amt) { data_recvd += amt; }
public:
Stats() : data_sent(0), data_recvd(0)
{ }
virtual ~Stats() { }
virtual uint64_t dataSent()
{
return data_sent;
}
virtual uint64_t dataRecvd()
{
return data_recvd;
}
virtual void dataSent(uint64_t amt)
{
data_sent += amt;
}
virtual void dataRecvd(uint64_t amt)
{
data_recvd += amt;
}
private:
uint64_t data_sent;
uint64_t data_recvd;
uint64_t data_sent;
uint64_t data_recvd;
};
/** an abstract socket class interface
@ -61,110 +73,110 @@ private:
class Socket
{
public:
/** dtor
*
*/
virtual ~Socket() {}
/** dtor
*
*/
virtual ~Socket() {}
/** open the socket
*
*/
virtual void open() = 0;
/** open the socket
*
*/
virtual void open() = 0;
/** read a message from the socket
*
* wait for and return a message from the socket. The deafult timeout waits forever. Note that
* eventhough struct timespec has nanosecond resolution, this method only has millisecond resolution.
*/
virtual const SBS read(const struct timespec* timeout=0, bool* isTimeOut = NULL, Stats *stats = NULL) const = 0;
/** read a message from the socket
*
* wait for and return a message from the socket. The deafult timeout waits forever. Note that
* eventhough struct timespec has nanosecond resolution, this method only has millisecond resolution.
*/
virtual const SBS read(const struct timespec* timeout = 0, bool* isTimeOut = NULL, Stats* stats = NULL) const = 0;
/** write a message to the socket
*
* write a message to the socket
*/
virtual void write(const ByteStream& msg, Stats *stats = NULL) = 0;
virtual void write_raw(const ByteStream& msg, Stats *stats = NULL) const = 0;
virtual void write(SBS msg, Stats *stats = NULL) = 0;
/** write a message to the socket
*
* write a message to the socket
*/
virtual void write(const ByteStream& msg, Stats* stats = NULL) = 0;
virtual void write_raw(const ByteStream& msg, Stats* stats = NULL) const = 0;
virtual void write(SBS msg, Stats* stats = NULL) = 0;
/** close the socket
*
*/
virtual void close() = 0;
/** close the socket
*
*/
virtual void close() = 0;
/** bind to a port
*
*/
virtual void bind(const struct sockaddr* serv_addr) = 0;
/** bind to a port
*
*/
virtual void bind(const struct sockaddr* serv_addr) = 0;
/** listen for connections
*
*/
virtual void listen(int backlog=5) = 0;
/** listen for connections
*
*/
virtual void listen(int backlog = 5) = 0;
/** return an (accepted) IOSocket ready for I/O
*
*/
virtual const IOSocket accept(const struct timespec* timeout=0) = 0;
/** return an (accepted) IOSocket ready for I/O
*
*/
virtual const IOSocket accept(const struct timespec* timeout = 0) = 0;
/** connect to a server socket
*
*/
virtual void connect(const sockaddr* serv_addr) = 0;
/** connect to a server socket
*
*/
virtual void connect(const sockaddr* serv_addr) = 0;
/** test if this socket is open
*
*/
virtual const bool isOpen() const = 0;
/** test if this socket is open
*
*/
virtual const bool isOpen() const = 0;
/** get the SocketParms
*
*/
virtual const SocketParms socketParms() const = 0;
/** get the SocketParms
*
*/
virtual const SocketParms socketParms() const = 0;
/** set the SocketParms
*
*/
virtual void socketParms(const SocketParms& socketParms) = 0;
/** set the SocketParms
*
*/
virtual void socketParms(const SocketParms& socketParms) = 0;
/** set the sockaddr struct
*
*/
virtual void sa(const sockaddr* sa) = 0;
/** set the sockaddr struct
*
*/
virtual void sa(const sockaddr* sa) = 0;
/** dynamically allocate a copy of this object
*
*/
virtual Socket* clone() const = 0;
/** dynamically allocate a copy of this object
*
*/
virtual Socket* clone() const = 0;
/** set the connection timeout (in ms)
*
*/
virtual void connectionTimeout(const struct ::timespec* timeout) = 0;
/** set the connection timeout (in ms)
*
*/
virtual void connectionTimeout(const struct ::timespec* timeout) = 0;
/** set the connection protocol to be synchronous
*
*/
virtual void syncProto(bool use) = 0;
/** set the connection protocol to be synchronous
*
*/
virtual void syncProto(bool use) = 0;
virtual const int getConnectionNum() const = 0;
virtual const int getConnectionNum() const = 0;
/** return the address as a string
*
*/
virtual const std::string addr2String() const = 0;
/** return the address as a string
*
*/
virtual const std::string addr2String() const = 0;
/** compare 2 addresses
*
*/
virtual const bool isSameAddr(const Socket* rhs) const = 0;
/** compare 2 addresses
*
*/
virtual const bool isSameAddr(const Socket* rhs) const = 0;
virtual bool isConnected() const = 0;
virtual bool isConnected() const = 0;
virtual bool hasData() const = 0;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
};

View File

@ -28,28 +28,32 @@
#ifndef SOCKETCLOSED_H_
#define SOCKETCLOSED_H_
namespace messageqcpp {
namespace messageqcpp
{
/** @brief A closed socket exception class
*
* Some sort of activity has been requested on a closed socket
*/
class SocketClosed : public std::exception
class SocketClosed : public std::exception
{
std::string _M_msg;
std::string _M_msg;
public:
/** Takes a character string describing the error. */
explicit
SocketClosed(const std::string& __arg) : _M_msg(__arg) { }
/** Takes a character string describing the error. */
explicit
SocketClosed(const std::string& __arg) : _M_msg(__arg) { }
virtual
~SocketClosed() throw() { }
virtual
~SocketClosed() throw() { }
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char*
what() const throw() { return _M_msg.c_str(); }
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char*
what() const throw()
{
return _M_msg.c_str();
}
};
}

View File

@ -23,10 +23,11 @@
#include "socketparms.h"
namespace messageqcpp {
namespace messageqcpp
{
SocketParms::SocketParms(int domain, int type, int protocol) :
fSd(-1), fDomain(domain), fType(type), fProtocol(protocol)
fSd(-1), fDomain(domain), fType(type), fProtocol(protocol)
{
}
@ -36,25 +37,25 @@ SocketParms::~SocketParms()
void SocketParms::doCopy(const SocketParms& rhs)
{
fSd = rhs.fSd;
fDomain = rhs.fDomain;
fType = rhs.fType;
fProtocol = rhs.fProtocol;
fSd = rhs.fSd;
fDomain = rhs.fDomain;
fType = rhs.fType;
fProtocol = rhs.fProtocol;
}
SocketParms::SocketParms(const SocketParms& rhs)
{
doCopy(rhs);
doCopy(rhs);
}
SocketParms& SocketParms::operator=(const SocketParms& rhs)
{
if (this != &rhs)
{
doCopy(rhs);
}
if (this != &rhs)
{
doCopy(rhs);
}
return *this;
return *this;
}
}

View File

@ -26,7 +26,8 @@
class MessageQTestSuite;
namespace messageqcpp {
namespace messageqcpp
{
/** a simple socket parameters class
*
@ -34,94 +35,121 @@ namespace messageqcpp {
class SocketParms
{
public:
/** ctor
*
*/
explicit SocketParms(int domain=-1, int type=-1, int protocol=-1);
/** ctor
*
*/
explicit SocketParms(int domain = -1, int type = -1, int protocol = -1);
/** dtor
*
*/
virtual ~SocketParms();
/** dtor
*
*/
virtual ~SocketParms();
/** copy ctor
*
*/
SocketParms(const SocketParms& rhs);
/** copy ctor
*
*/
SocketParms(const SocketParms& rhs);
/** assign op
*
*/
SocketParms& operator=(const SocketParms& rhs);
/** assign op
*
*/
SocketParms& operator=(const SocketParms& rhs);
/** accessor
*
*/
inline int sd() const;
/** accessor
*
*/
inline int sd() const;
/** accessor
*
*/
inline int domain() const;
/** accessor
*
*/
inline int domain() const;
/** accessor
*
*/
inline int type() const;
/** accessor
*
*/
inline int type() const;
/** accessor
*
*/
inline int protocol() const;
/** accessor
*
*/
inline int protocol() const;
/** mutator
*
*/
inline void sd(int sd);
/** mutator
*
*/
inline void sd(int sd);
/** mutator
*
*/
inline void domain(int domain);
/** mutator
*
*/
inline void domain(int domain);
/** mutator
*
*/
inline void type(int type);
/** mutator
*
*/
inline void type(int type);
/** mutator
*
*/
inline void protocol(int protocol);
/** mutator
*
*/
inline void protocol(int protocol);
/** isOpen test
*
*/
inline bool isOpen() const;
/** isOpen test
*
*/
inline bool isOpen() const;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
/*
* allow test suite access to private data for OOB test
*/
friend class ::MessageQTestSuite;
private:
void doCopy(const SocketParms& rhs);
void doCopy(const SocketParms& rhs);
int fSd; /// the socket descriptor
int fDomain; /// the socket domain
int fType; /// the socket type
int fProtocol; /// the socket protocol
int fSd; /// the socket descriptor
int fDomain; /// the socket domain
int fType; /// the socket type
int fProtocol; /// the socket protocol
};
inline int SocketParms::sd() const { return fSd; }
inline int SocketParms::domain() const { return fDomain; }
inline int SocketParms::type() const { return fType; }
inline int SocketParms::protocol() const { return fProtocol; }
inline bool SocketParms::isOpen() const { return (fSd >= 0); }
inline void SocketParms::sd(int sd) { fSd = sd; }
inline void SocketParms::domain(int domain) { fDomain = domain; }
inline void SocketParms::type(int type) { fType = type; }
inline void SocketParms::protocol(int protocol) { fProtocol = protocol; }
inline int SocketParms::sd() const
{
return fSd;
}
inline int SocketParms::domain() const
{
return fDomain;
}
inline int SocketParms::type() const
{
return fType;
}
inline int SocketParms::protocol() const
{
return fProtocol;
}
inline bool SocketParms::isOpen() const
{
return (fSd >= 0);
}
inline void SocketParms::sd(int sd)
{
fSd = sd;
}
inline void SocketParms::domain(int domain)
{
fDomain = domain;
}
inline void SocketParms::type(int type)
{
fType = type;
}
inline void SocketParms::protocol(int protocol)
{
fProtocol = protocol;
}
} //namespace messageqcpp

View File

@ -9,30 +9,33 @@ using namespace config;
int main(int argc, char** argv)
{
Config* cf = Config::makeConfig("./Columnstore.xml");
MessageQueueServer mqs("server1", cf);
Config* cf = Config::makeConfig("./Columnstore.xml");
MessageQueueServer mqs("server1", cf);
cout << "server ready..." << endl;
cout << "server ready..." << endl;
IOSocket ios;
ByteStream ibs;
ByteStream obs;
uint32_t qb = 0;
while (1)
{
ios = mqs.accept();
ibs = ios.read();
while (ibs.length() > 0)
{
cout << "read " << ibs.length() << " bytes from " << ios << endl;
obs.restart();
obs << qb;
ios.write(obs);
ibs = ios.read();
}
ios.close();
}
IOSocket ios;
ByteStream ibs;
ByteStream obs;
uint32_t qb = 0;
return 0;
while (1)
{
ios = mqs.accept();
ibs = ios.read();
while (ibs.length() > 0)
{
cout << "read " << ibs.length() << " bytes from " << ios << endl;
obs.restart();
obs << qb;
ios.write(obs);
ibs = ios.read();
}
ios.close();
}
return 0;
}

File diff suppressed because it is too large Load Diff