mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 05:34:48 +02:00
Cleaned up TcpClient interface.
This commit is contained in:
parent
07b30e19a9
commit
802fc15969
@ -21,6 +21,7 @@ libbase_la_SOURCES = \
|
|||||||
fifo.cpp \
|
fifo.cpp \
|
||||||
fifo.h \
|
fifo.h \
|
||||||
i2-base.h \
|
i2-base.h \
|
||||||
|
ioqueue.h \
|
||||||
logger.cpp \
|
logger.cpp \
|
||||||
logger.h \
|
logger.h \
|
||||||
object.cpp \
|
object.cpp \
|
||||||
|
@ -69,7 +69,7 @@ public:
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Run();
|
Run();
|
||||||
} catch (const exception& ex) {
|
} catch (const exception&) {
|
||||||
FinishException(boost::current_exception());
|
FinishException(boost::current_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
<ClInclude Include="configobject.h" />
|
<ClInclude Include="configobject.h" />
|
||||||
<ClInclude Include="dictionary.h" />
|
<ClInclude Include="dictionary.h" />
|
||||||
<ClInclude Include="event.h" />
|
<ClInclude Include="event.h" />
|
||||||
|
<ClInclude Include="ioqueue.h" />
|
||||||
<ClInclude Include="scriptfunction.h" />
|
<ClInclude Include="scriptfunction.h" />
|
||||||
<ClInclude Include="scripttask.h" />
|
<ClInclude Include="scripttask.h" />
|
||||||
<ClInclude Include="logger.h" />
|
<ClInclude Include="logger.h" />
|
||||||
|
@ -180,6 +180,9 @@
|
|||||||
<ClInclude Include="scriptfunction.h">
|
<ClInclude Include="scriptfunction.h">
|
||||||
<Filter>Headerdateien</Filter>
|
<Filter>Headerdateien</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ioqueue.h">
|
||||||
|
<Filter>Headerdateien</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Quelldateien">
|
<Filter Include="Quelldateien">
|
||||||
|
@ -93,11 +93,9 @@ void FIFO::Optimize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of bytes that are contained in the FIFO.
|
* Implements IOQueue::GetAvailableBytes().
|
||||||
*
|
|
||||||
* @returns The number of bytes.
|
|
||||||
*/
|
*/
|
||||||
size_t FIFO::GetSize(void) const
|
size_t FIFO::GetAvailableBytes(void) const
|
||||||
{
|
{
|
||||||
return m_DataSize;
|
return m_DataSize;
|
||||||
}
|
}
|
||||||
@ -107,32 +105,33 @@ size_t FIFO::GetSize(void) const
|
|||||||
*
|
*
|
||||||
* @returns Pointer to the read buffer.
|
* @returns Pointer to the read buffer.
|
||||||
*/
|
*/
|
||||||
const void *FIFO::GetReadBuffer(void) const
|
/*const void *FIFO::GetReadBuffer(void) const
|
||||||
{
|
{
|
||||||
return m_Buffer + m_Offset;
|
return m_Buffer + m_Offset;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads data from the FIFO and places it in the specified buffer.
|
* Implements IOQueue::Peek.
|
||||||
*
|
|
||||||
* @param buffer The buffer where the data should be placed (can be NULL if
|
|
||||||
* the reader is not interested in the data).
|
|
||||||
* @param count The number of bytes to read.
|
|
||||||
* @returns The number of bytes read which may be less than what was requested.
|
|
||||||
*/
|
*/
|
||||||
size_t FIFO::Read(void *buffer, size_t count)
|
void FIFO::Peek(void *buffer, size_t count)
|
||||||
{
|
{
|
||||||
count = (count <= m_DataSize) ? count : m_DataSize;
|
assert(m_DataSize >= count);
|
||||||
|
|
||||||
if (buffer != NULL)
|
if (buffer != NULL)
|
||||||
memcpy(buffer, m_Buffer + m_Offset, count);
|
memcpy(buffer, m_Buffer + m_Offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IOQueue::Read.
|
||||||
|
*/
|
||||||
|
void FIFO::Read(void *buffer, size_t count)
|
||||||
|
{
|
||||||
|
Peek(buffer, count);
|
||||||
|
|
||||||
m_DataSize -= count;
|
m_DataSize -= count;
|
||||||
m_Offset += count;
|
m_Offset += count;
|
||||||
|
|
||||||
Optimize();
|
Optimize();
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,31 +141,20 @@ size_t FIFO::Read(void *buffer, size_t count)
|
|||||||
* contains the actual size of the available buffer which can
|
* contains the actual size of the available buffer which can
|
||||||
* be larger than the requested size.
|
* be larger than the requested size.
|
||||||
*/
|
*/
|
||||||
void *FIFO::GetWriteBuffer(size_t *count)
|
/*void *FIFO::GetWriteBuffer(size_t *count)
|
||||||
{
|
{
|
||||||
ResizeBuffer(m_Offset + m_DataSize + *count);
|
ResizeBuffer(m_Offset + m_DataSize + *count);
|
||||||
*count = m_AllocSize - m_Offset - m_DataSize;
|
*count = m_AllocSize - m_Offset - m_DataSize;
|
||||||
|
|
||||||
return m_Buffer + m_Offset + m_DataSize;
|
return m_Buffer + m_Offset + m_DataSize;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes data to the FIFO.
|
* Implements IOQueue::Write.
|
||||||
*
|
|
||||||
* @param buffer The data that is to be written (can be NULL if the writer has
|
|
||||||
* already filled the write buffer, e.g. via GetWriteBuffer()).
|
|
||||||
* @param count The number of bytes to write.
|
|
||||||
* @returns The number of bytes written
|
|
||||||
*/
|
*/
|
||||||
size_t FIFO::Write(const void *buffer, size_t count)
|
void FIFO::Write(const void *buffer, size_t count)
|
||||||
{
|
{
|
||||||
if (buffer != NULL) {
|
ResizeBuffer(m_Offset + m_DataSize + count);
|
||||||
size_t bufferSize = count;
|
memcpy(m_Buffer + m_Offset + m_DataSize, buffer, count);
|
||||||
void *target_buffer = GetWriteBuffer(&bufferSize);
|
|
||||||
memcpy(target_buffer, buffer, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DataSize += count;
|
m_DataSize += count;
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
14
base/fifo.h
14
base/fifo.h
@ -28,7 +28,7 @@ namespace icinga
|
|||||||
*
|
*
|
||||||
* @ingroup base
|
* @ingroup base
|
||||||
*/
|
*/
|
||||||
class I2_BASE_API FIFO : public Object
|
class I2_BASE_API FIFO : public Object, public IOQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const size_t BlockSize = 16 * 1024;
|
static const size_t BlockSize = 16 * 1024;
|
||||||
@ -39,13 +39,13 @@ public:
|
|||||||
FIFO(void);
|
FIFO(void);
|
||||||
~FIFO(void);
|
~FIFO(void);
|
||||||
|
|
||||||
size_t GetSize(void) const;
|
/*const void *GetReadBuffer(void) const;
|
||||||
|
void *GetWriteBuffer(size_t *count);*/
|
||||||
|
|
||||||
const void *GetReadBuffer(void) const;
|
virtual size_t GetAvailableBytes(void) const;
|
||||||
void *GetWriteBuffer(size_t *count);
|
virtual void Peek(void *buffer, size_t count);
|
||||||
|
virtual void Read(void *buffer, size_t count);
|
||||||
size_t Read(void *buffer, size_t count);
|
virtual void Write(const void *buffer, size_t count);
|
||||||
size_t Write(const void *buffer, size_t count);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *m_Buffer;
|
char *m_Buffer;
|
||||||
|
@ -161,6 +161,7 @@ using boost::system_time;
|
|||||||
#include "dictionary.h"
|
#include "dictionary.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "ioqueue.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "tcpsocket.h"
|
#include "tcpsocket.h"
|
||||||
|
54
base/ioqueue.h
Normal file
54
base/ioqueue.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef IOQUEUE_H
|
||||||
|
#define IOQUEUE_H
|
||||||
|
|
||||||
|
namespace icinga
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An I/O queue.
|
||||||
|
*/
|
||||||
|
class IOQueue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Retrieves the number of bytes available for reading.
|
||||||
|
*
|
||||||
|
* @returns The number of available bytes.
|
||||||
|
*/
|
||||||
|
virtual size_t GetAvailableBytes(void) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads data from the queue without advancing the read pointer. Trying
|
||||||
|
* to read more data than is available in the queue is a programming error.
|
||||||
|
* Use GetBytesAvailable() to check how much data is available.
|
||||||
|
*
|
||||||
|
* @buffer The buffer where data should be stored. May be NULL if you're
|
||||||
|
* not actually interested in the data.
|
||||||
|
* @param count The number of bytes to read from the queue.
|
||||||
|
*/
|
||||||
|
virtual void Peek(void *buffer, size_t count) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads data from the queue. Trying to read more data than is
|
||||||
|
* available in the queue is a programming error. Use GetBytesAvailable()
|
||||||
|
* to check how much data is available.
|
||||||
|
*
|
||||||
|
* @param buffer The buffer where data should be stored. May be NULL if you're
|
||||||
|
* not actually interested in the data.
|
||||||
|
* @param count The number of bytes to read from the queue.
|
||||||
|
*/
|
||||||
|
virtual void Read(void *buffer, size_t count) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes data to the queue.
|
||||||
|
*
|
||||||
|
* @param buffer The data that is to be written.
|
||||||
|
* @param count The number of bytes to write.
|
||||||
|
* @returns The number of bytes written
|
||||||
|
*/
|
||||||
|
virtual void Write(const void *buffer, size_t count) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* IOQUEUE_H */
|
@ -103,21 +103,24 @@ void TcpClient::Connect(const string& node, const string& service)
|
|||||||
"Could not create a suitable socket."));
|
"Could not create a suitable socket."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the send queue for the socket.
|
|
||||||
*
|
|
||||||
* @returns The send queue.
|
|
||||||
*/
|
|
||||||
FIFO::Ptr TcpClient::GetSendQueue(void)
|
|
||||||
{
|
|
||||||
return m_SendQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TcpClient::HandleWritable(void)
|
void TcpClient::HandleWritable(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
char data[1024];
|
||||||
|
size_t count;
|
||||||
|
|
||||||
rc = send(GetFD(), (const char *)m_SendQueue->GetReadBuffer(), m_SendQueue->GetSize(), 0);
|
for (;;) {
|
||||||
|
count = m_SendQueue->GetAvailableBytes();
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (count > sizeof(data))
|
||||||
|
count = sizeof(data);
|
||||||
|
|
||||||
|
m_SendQueue->Peek(data, count);
|
||||||
|
|
||||||
|
rc = send(GetFD(), (const char *)data, count, 0);
|
||||||
|
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
HandleSocketError(SocketException("send() failed", GetError()));
|
HandleSocketError(SocketException("send() failed", GetError()));
|
||||||
@ -125,24 +128,54 @@ void TcpClient::HandleWritable(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_SendQueue->Read(NULL, rc);
|
m_SendQueue->Read(NULL, rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the recv queue for the socket.
|
* Implements IOQueue::GetAvailableBytes.
|
||||||
*
|
|
||||||
* @returns The recv queue.
|
|
||||||
*/
|
*/
|
||||||
FIFO::Ptr TcpClient::GetRecvQueue(void)
|
size_t TcpClient::GetAvailableBytes(void) const
|
||||||
{
|
{
|
||||||
return m_RecvQueue;
|
mutex::scoped_lock lock(GetMutex());
|
||||||
|
|
||||||
|
return m_RecvQueue->GetAvailableBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IOQueue::Peek.
|
||||||
|
*/
|
||||||
|
void TcpClient::Peek(void *buffer, size_t count)
|
||||||
|
{
|
||||||
|
mutex::scoped_lock lock(GetMutex());
|
||||||
|
|
||||||
|
m_RecvQueue->Peek(buffer, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IOQueue::Read.
|
||||||
|
*/
|
||||||
|
void TcpClient::Read(void *buffer, size_t count)
|
||||||
|
{
|
||||||
|
mutex::scoped_lock lock(GetMutex());
|
||||||
|
|
||||||
|
m_RecvQueue->Read(buffer, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements IOQueue::Write.
|
||||||
|
*/
|
||||||
|
void TcpClient::Write(const void *buffer, size_t count)
|
||||||
|
{
|
||||||
|
mutex::scoped_lock lock(GetMutex());
|
||||||
|
|
||||||
|
m_SendQueue->Write(buffer, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpClient::HandleReadable(void)
|
void TcpClient::HandleReadable(void)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t bufferSize = FIFO::BlockSize / 2;
|
char data[1024];
|
||||||
char *buffer = (char *)m_RecvQueue->GetWriteBuffer(&bufferSize);
|
int rc = recv(GetFD(), data, sizeof(data), 0);
|
||||||
int rc = recv(GetFD(), buffer, bufferSize, 0);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (rc < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
|
if (rc < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
|
||||||
@ -156,7 +189,7 @@ void TcpClient::HandleReadable(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_RecvQueue->Write(NULL, rc);
|
m_RecvQueue->Write(data, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::Post(boost::bind(boost::ref(OnDataAvailable), GetSelf()));
|
Event::Post(boost::bind(boost::ref(OnDataAvailable), GetSelf()));
|
||||||
@ -179,7 +212,7 @@ bool TcpClient::WantsToRead(void) const
|
|||||||
*/
|
*/
|
||||||
bool TcpClient::WantsToWrite(void) const
|
bool TcpClient::WantsToWrite(void) const
|
||||||
{
|
{
|
||||||
return (m_SendQueue->GetSize() > 0);
|
return (m_SendQueue->GetAvailableBytes() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +41,7 @@ enum TcpClientRole
|
|||||||
*
|
*
|
||||||
* @ingroup base
|
* @ingroup base
|
||||||
*/
|
*/
|
||||||
class I2_BASE_API TcpClient : public TcpSocket
|
class I2_BASE_API TcpClient : public TcpSocket, public IOQueue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef shared_ptr<TcpClient> Ptr;
|
typedef shared_ptr<TcpClient> Ptr;
|
||||||
@ -53,11 +53,13 @@ public:
|
|||||||
|
|
||||||
void Connect(const string& node, const string& service);
|
void Connect(const string& node, const string& service);
|
||||||
|
|
||||||
FIFO::Ptr GetSendQueue(void);
|
|
||||||
FIFO::Ptr GetRecvQueue(void);
|
|
||||||
|
|
||||||
boost::signal<void (const TcpClient::Ptr&)> OnDataAvailable;
|
boost::signal<void (const TcpClient::Ptr&)> OnDataAvailable;
|
||||||
|
|
||||||
|
virtual size_t GetAvailableBytes(void) const;
|
||||||
|
virtual void Peek(void *buffer, size_t count);
|
||||||
|
virtual void Read(void *buffer, size_t count);
|
||||||
|
virtual void Write(const void *buffer, size_t count);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool WantsToRead(void) const;
|
virtual bool WantsToRead(void) const;
|
||||||
virtual bool WantsToWrite(void) const;
|
virtual bool WantsToWrite(void) const;
|
||||||
@ -65,11 +67,11 @@ protected:
|
|||||||
virtual void HandleReadable(void);
|
virtual void HandleReadable(void);
|
||||||
virtual void HandleWritable(void);
|
virtual void HandleWritable(void);
|
||||||
|
|
||||||
private:
|
|
||||||
TcpClientRole m_Role;
|
|
||||||
|
|
||||||
FIFO::Ptr m_SendQueue;
|
FIFO::Ptr m_SendQueue;
|
||||||
FIFO::Ptr m_RecvQueue;
|
FIFO::Ptr m_RecvQueue;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TcpClientRole m_Role;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,9 +117,8 @@ void TlsClient::HandleReadable(void)
|
|||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t bufferSize = FIFO::BlockSize / 2;
|
char data[1024];
|
||||||
char *buffer = (char *)GetRecvQueue()->GetWriteBuffer(&bufferSize);
|
int rc = SSL_read(m_SSL.get(), data, sizeof(data));
|
||||||
int rc = SSL_read(m_SSL.get(), buffer, bufferSize);
|
|
||||||
|
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||||
@ -138,7 +137,7 @@ void TlsClient::HandleReadable(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetRecvQueue()->Write(NULL, rc);
|
m_RecvQueue->Write(data, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
post_event:
|
post_event:
|
||||||
@ -153,7 +152,21 @@ void TlsClient::HandleWritable(void)
|
|||||||
m_BlockRead = false;
|
m_BlockRead = false;
|
||||||
m_BlockWrite = false;
|
m_BlockWrite = false;
|
||||||
|
|
||||||
int rc = SSL_write(m_SSL.get(), (const char *)GetSendQueue()->GetReadBuffer(), GetSendQueue()->GetSize());
|
char data[1024];
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
count = m_SendQueue->GetAvailableBytes();
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (count > sizeof(data))
|
||||||
|
count = sizeof(data);
|
||||||
|
|
||||||
|
m_SendQueue->Peek(data, count);
|
||||||
|
|
||||||
|
int rc = SSL_write(m_SSL.get(), (const char *)data, count);
|
||||||
|
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
switch (SSL_get_error(m_SSL.get(), rc)) {
|
switch (SSL_get_error(m_SSL.get(), rc)) {
|
||||||
@ -172,7 +185,8 @@ void TlsClient::HandleWritable(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetSendQueue()->Read(NULL, rc);
|
m_SendQueue->Read(NULL, rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user