Non-blocking socket input/output.
This commit is contained in:
parent
c2a41984af
commit
344d96539d
@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||||
|
#include <sched.h>
|
||||||
|
#endif // _POSIX_PRIORITY_SCHEDULING
|
||||||
|
|
||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
namespace platforms {
|
namespace platforms {
|
||||||
@ -201,7 +205,11 @@ vmime::utility::childProcessFactory* posixHandler::getChildProcessFactory() cons
|
|||||||
|
|
||||||
void posixHandler::wait() const
|
void posixHandler::wait() const
|
||||||
{
|
{
|
||||||
|
#ifdef _POSIX_PRIORITY_SCHEDULING
|
||||||
|
::sched_yield();
|
||||||
|
#else
|
||||||
::sleep(1);
|
::sleep(1);
|
||||||
|
#endif // _POSIX_PRIORITY_SCHEDULING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "vmime/platforms/posix/posixSocket.hpp"
|
#include "vmime/platforms/posix/posixSocket.hpp"
|
||||||
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -121,12 +122,19 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
|
|||||||
("Error while connecting socket.", e);
|
("Error while connecting socket.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::fcntl(m_desc, F_SETFL, ::fcntl(m_desc, F_GETFL) | O_NONBLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool posixSocket::isConnected() const
|
const bool posixSocket::isConnected() const
|
||||||
{
|
{
|
||||||
return (m_desc != -1);
|
if (m_desc == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char buff;
|
||||||
|
|
||||||
|
return ::recv(m_desc, &buff, 1, MSG_PEEK) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -144,47 +152,60 @@ void posixSocket::disconnect()
|
|||||||
|
|
||||||
void posixSocket::receive(vmime::string& buffer)
|
void posixSocket::receive(vmime::string& buffer)
|
||||||
{
|
{
|
||||||
::ssize_t ret = ::recv(m_desc, m_buffer, sizeof(m_buffer), 0);
|
const int size = receiveRaw(m_buffer, sizeof(m_buffer));
|
||||||
|
buffer = vmime::string(m_buffer, size);
|
||||||
if (ret == -1)
|
|
||||||
{
|
|
||||||
// Error or no data
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (ret > 0)
|
|
||||||
{
|
|
||||||
buffer = vmime::string(m_buffer, ret);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int posixSocket::receiveRaw(char* buffer, const int count)
|
const int posixSocket::receiveRaw(char* buffer, const int count)
|
||||||
{
|
{
|
||||||
::ssize_t ret = ::recv(m_desc, buffer, count, 0);
|
const int ret = ::recv(m_desc, buffer, count, 0);
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
// Error or no data
|
if (errno != EAGAIN)
|
||||||
return (0);
|
throwSocketError(errno);
|
||||||
|
|
||||||
|
// No data available at this time
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else if (ret == 0)
|
||||||
{
|
{
|
||||||
return (ret);
|
// Host shutdown
|
||||||
|
throwSocketError(ENOTCONN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void posixSocket::send(const vmime::string& buffer)
|
void posixSocket::send(const vmime::string& buffer)
|
||||||
{
|
{
|
||||||
if (::send(m_desc, buffer.data(), buffer.length(), 0) == -1)
|
sendRaw(buffer.data(), buffer.length());
|
||||||
throwSocketError(errno);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void posixSocket::sendRaw(const char* buffer, const int count)
|
void posixSocket::sendRaw(const char* buffer, const int count)
|
||||||
{
|
{
|
||||||
if (::send(m_desc, buffer, count, 0) == -1)
|
int size = count;
|
||||||
|
|
||||||
|
while (size > 0)
|
||||||
|
{
|
||||||
|
const int ret = ::send(m_desc, buffer, size, 0);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
throwSocketError(errno);
|
throwSocketError(errno);
|
||||||
|
|
||||||
|
platformDependant::getHandler()->wait();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer += ret;
|
||||||
|
size -= ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user