1/*
2 * IXSocket.h
3 * Author: Benjamin Sergeant
4 * Copyright (c) 2017-2018 Machine Zone, Inc. All rights reserved.
5 */
6
7#pragma once
8
9#include <atomic>
10#include <functional>
11#include <memory>
12#include <mutex>
13#include <string>
14
15#ifdef _WIN32
16#include <basetsd.h>
17#ifdef _MSC_VER
18typedef SSIZE_T ssize_t;
19#endif
20#endif
21
22#include "IXCancellationRequest.h"
23#include "IXProgressCallback.h"
24#include "IXSelectInterrupt.h"
25
26namespace ix
27{
28 enum class PollResultType
29 {
30 ReadyForRead = 0,
31 ReadyForWrite = 1,
32 Timeout = 2,
33 Error = 3,
34 SendRequest = 4,
35 CloseRequest = 5
36 };
37
38 class Socket
39 {
40 public:
41 Socket(int fd = -1);
42 virtual ~Socket();
43 bool init(std::string& errorMsg);
44
45 // Functions to check whether there is activity on the socket
46 PollResultType poll(int timeoutMs = kDefaultPollTimeout);
47 bool wakeUpFromPoll(uint64_t wakeUpCode);
48 bool isWakeUpFromPollSupported();
49
50 PollResultType isReadyToWrite(int timeoutMs);
51 PollResultType isReadyToRead(int timeoutMs);
52
53 // Virtual methods
54 virtual bool accept(std::string& errMsg);
55
56 virtual bool connect(const std::string& host,
57 int port,
58 std::string& errMsg,
59 const CancellationRequest& isCancellationRequested);
60 virtual void close();
61
62 virtual ssize_t send(char* buffer, size_t length);
63 ssize_t send(const std::string& buffer);
64 virtual ssize_t recv(void* buffer, size_t length);
65
66 // Blocking and cancellable versions, working with socket that can be set
67 // to non blocking mode. Used during HTTP upgrade.
68 bool readByte(void* buffer, const CancellationRequest& isCancellationRequested);
69 bool writeBytes(const std::string& str, const CancellationRequest& isCancellationRequested);
70
71 std::pair<bool, std::string> readLine(const CancellationRequest& isCancellationRequested);
72 std::pair<bool, std::string> readBytes(size_t length,
73 const OnProgressCallback& onProgressCallback,
74 const OnChunkCallback& onChunkCallback,
75 const CancellationRequest& isCancellationRequested);
76
77 static int getErrno();
78 static bool isWaitNeeded();
79 static void closeSocket(int fd);
80
81 static PollResultType poll(bool readyToRead,
82 int timeoutMs,
83 int sockfd,
84 const SelectInterruptPtr& selectInterrupt);
85
86 protected:
87 std::atomic<int> _sockfd;
88 std::mutex _socketMutex;
89
90 static bool readSelectInterruptRequest(const SelectInterruptPtr& selectInterrupt,
91 PollResultType* pollResult);
92
93 private:
94 static const int kDefaultPollTimeout;
95 static const int kDefaultPollNoTimeout;
96
97 SelectInterruptPtr _selectInterrupt;
98 };
99} // namespace ix
100