IXWebSocket/ixwebsocket/IXSocket.h

119 lines
3.4 KiB
C
Raw Normal View History

2018-09-27 23:56:48 +02:00
/*
* IXSocket.h
* Author: Benjamin Sergeant
* Copyright (c) 2017-2018 Machine Zone, Inc. All rights reserved.
*/
#pragma once
2019-05-30 17:46:50 +02:00
#include <atomic>
2018-09-27 23:56:48 +02:00
#include <functional>
2019-05-30 17:46:50 +02:00
#include <memory>
2018-09-27 23:56:48 +02:00
#include <mutex>
2019-05-30 17:46:50 +02:00
#include <string>
#include <vector>
2018-09-27 23:56:48 +02:00
2019-01-06 06:02:55 +01:00
#ifdef _WIN32
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#undef EWOULDBLOCK
#undef EAGAIN
#undef EINPROGRESS
#undef EBADF
#undef EINVAL
// map to WSA error codes
2019-05-30 17:46:50 +02:00
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EAGAIN WSATRY_AGAIN
#define EINPROGRESS WSAEINPROGRESS
#define EBADF WSAEBADF
#define EINVAL WSAEINVAL
2019-01-06 06:02:55 +01:00
#endif
2018-12-15 01:28:11 +01:00
#include "IXCancellationRequest.h"
#include "IXProgressCallback.h"
namespace ix
2018-09-27 23:56:48 +02:00
{
2019-03-15 02:37:38 +01:00
class SelectInterrupt;
using SelectInterruptPtr = std::unique_ptr<SelectInterrupt>;
2019-03-15 02:37:38 +01:00
2019-03-19 17:29:57 +01:00
enum class PollResultType
2019-01-24 21:42:49 +01:00
{
2019-05-30 17:46:50 +02:00
ReadyForRead = 0,
ReadyForWrite = 1,
Timeout = 2,
Error = 3,
SendRequest = 4,
CloseRequest = 5
2019-01-24 21:42:49 +01:00
};
2019-05-30 17:46:50 +02:00
class Socket
{
2018-09-27 23:56:48 +02:00
public:
2018-12-30 06:53:33 +01:00
Socket(int fd = -1);
2018-09-27 23:56:48 +02:00
virtual ~Socket();
2019-03-15 02:37:38 +01:00
bool init(std::string& errorMsg);
2018-09-27 23:56:48 +02:00
// Functions to check whether there is activity on the socket
PollResultType poll(int timeoutMs = kDefaultPollTimeout);
bool wakeUpFromPoll(uint64_t wakeUpCode);
2019-03-19 01:54:51 +01:00
PollResultType isReadyToWrite(int timeoutMs);
PollResultType isReadyToRead(int timeoutMs);
2018-09-27 23:56:48 +02:00
// Virtual methods
virtual bool accept(std::string& errMsg);
virtual bool connect(const std::string& host,
2018-09-27 23:56:48 +02:00
int port,
std::string& errMsg,
2018-12-15 01:28:11 +01:00
const CancellationRequest& isCancellationRequested);
2018-09-27 23:56:48 +02:00
virtual void close();
virtual ssize_t send(char* buffer, size_t length);
2020-01-13 07:30:16 +01:00
ssize_t send(const std::string& buffer);
virtual ssize_t recv(void* buffer, size_t length);
2018-09-27 23:56:48 +02:00
// Blocking and cancellable versions, working with socket that can be set
// to non blocking mode. Used during HTTP upgrade.
2019-05-30 17:46:50 +02:00
bool readByte(void* buffer, const CancellationRequest& isCancellationRequested);
bool writeBytes(const std::string& str, const CancellationRequest& isCancellationRequested);
std::pair<bool, std::string> readLine(const CancellationRequest& isCancellationRequested);
std::pair<bool, std::string> readBytes(size_t length,
const OnProgressCallback& onProgressCallback,
const CancellationRequest& isCancellationRequested);
2019-01-05 02:28:13 +01:00
static int getErrno();
2019-05-06 18:13:42 +02:00
static bool isWaitNeeded();
static void closeSocket(int fd);
2018-10-09 06:42:45 +02:00
static PollResultType poll(bool readyToRead,
int timeoutMs,
int sockfd,
const SelectInterruptPtr& selectInterrupt);
// Used as special codes for pipe communication
static const uint64_t kSendRequest;
static const uint64_t kCloseRequest;
2018-09-27 23:56:48 +02:00
protected:
std::atomic<int> _sockfd;
std::mutex _socketMutex;
2019-01-24 21:42:49 +01:00
private:
static const int kDefaultPollTimeout;
static const int kDefaultPollNoTimeout;
// Buffer for reading from our socket. That buffer is never resized.
std::vector<uint8_t> _readBuffer;
static constexpr size_t kChunkSize = 1 << 15;
SelectInterruptPtr _selectInterrupt;
2018-09-27 23:56:48 +02:00
};
2019-05-30 17:46:50 +02:00
} // namespace ix