]> git.cworth.org Git - vogl/blob - src/common/channel.h
Initial vogl checkin
[vogl] / src / common / channel.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #pragma once
27
28 #include <pthread.h>
29 #include "mtqueue.h"
30
31 namespace network
32 {
33
34     //  Error code constants
35     typedef enum
36     {
37         EC_NONE = 0,
38         EC_NETWORK,
39         EC_TIMEOUT,
40         EC_MEMORY,
41         EC_SYSTEM,
42         EC_NOTALLOWED
43     } CHEC;
44
45     class channel
46     {
47     public:
48         channel(void *pbFixedBuffer, size_t cbFixedBuffer);
49         channel();
50
51         ~channel();
52
53         CHEC Connect(char *szServer, int port, int nRetries, unsigned int waitMS); // Connecting side
54         CHEC Connect(int port, int backlog, bool fLocal);                          // Accepting side
55
56         CHEC Disconnect();
57
58         CHEC ReadMsg(unsigned int *pcbBufOut, char **ppBufOut, int nRetries, int timoutMS);
59         CHEC WriteMsg(unsigned int cbBufIn, const char *pbBufIn, int nRetries, int timeoutMS);
60
61     private:
62         volatile int m_socket;
63         bool m_fServer;
64         int m_port;
65
66         char m_szServer[128];
67         void *m_pbFixedBuffer;
68         size_t m_cbFixedBuffer;
69
70         bool m_fLocal;
71         int m_listenSocket;
72         int m_backlog;
73
74         void Initialize(void *pbFixedBuffer, size_t cbFixedBuffer);
75
76         CHEC acceptConnection();
77         CHEC connectConnection();
78         CHEC channelConnect();
79
80         CHEC readMsgLoop(unsigned int *pcbBufOut, char **ppBufOut, int timoutMS);
81         CHEC writeMsgLoop(unsigned int cbBufIn, const char *pbBufIn, int timeoutMS);
82
83         CHEC readMsgTimeout(unsigned int cbSize, char *pBuff, int timeoutMS);
84         CHEC writeMsgTimeout(unsigned int cbSize, const char *pBuff, int timeoutMS);
85
86         void *my_malloc(size_t cbSize);
87         void my_free(void *pBuff);
88     };
89
90     //  These function callbacks are called on their own threads.  Implementations of these functions should ensure that any data they
91     //  need to access is managed appropriately.
92     typedef void (*FnReadCallbackPtr)(void *callbackParam, unsigned int cbData, char *pgData);
93     typedef void (*FnRRCallbackPtr)(void *callbackParam, unsigned int cbReq, char *pbReq, unsigned int *pcbResp, char **ppbResp);
94
95     //  Service Masks
96     //  OR'ing these masks together say how what kind of connections the channel manager will be managing.
97     #define REQRESP   0x01  //  Request Response service
98     #define RECVASYNC 0x02  //  Receive Async messages
99     #define SENDASYNC 0x04  //  Send Async messages
100
101     class channelmgr
102     {
103     public:
104         channelmgr();
105         ~channelmgr();
106
107         CHEC Connect(char *szServer, int port, char serviceMask, FnReadCallbackPtr recvCallbackfn, void *recvCallbackParam);
108         CHEC Accept(int port, char serviceMask, bool fLocal, FnReadCallbackPtr readCallbackfn, void *readCallbackParam, FnRRCallbackPtr reqCallbackfn, void *reqCallbackParam);
109
110         //  SendData is thread safe and can be called from any thread.  Messages will queue if the connection is slow or interrupted.
111         CHEC SendData(unsigned int cbData, char *pbData, FnReadCallbackPtr respCallbackfn, void *respCallbackParam);
112         CHEC SendData(unsigned int cbData, char *pbData);
113
114         bool HasError(int *perrno);
115
116         void Disconnect();
117
118         // Listens for receiving data and calls the recvCallbackfn() with any data it gets
119         void DriveRecvLoop(); 
120         // Reads from the SendQueue and sends across the socket anything coming its way.
121         void DriveSendLoop();
122
123         // Listens for receiving data and calls the reqrespCallbackfn() with any data it gets, and sends
124         // back the response syncronously.
125         void DriveReqRespRecvLoop();
126         // Reads from the ReqRespSendQueue and sends across the socket anything coming its way
127         void DriveReqRespSendLoop();
128
129     private:
130
131         int m_basePort;
132         int m_errno;
133         bool m_fTerminate;
134         bool m_fServer;
135         bool m_fLocal;
136         char m_server[128];
137
138         volatile bool m_fReadyRecvAsync;
139         volatile bool m_fReadySendAsync;
140         volatile bool m_fReadyReqResp;
141
142         channel *m_pReqRespChannel;
143         channel *m_pSendChannel;
144         channel *m_pRecvChannel;
145
146         pthread_t m_threadRecv;
147         FnReadCallbackPtr m_recvCallbackfn;
148         void * m_recvCallbackParam;
149
150         pthread_t m_threadReqRespRecv;
151         FnRRCallbackPtr m_reqCallbackfn;
152         void * m_reqCallbackParam;
153
154
155         CHEC SendDataInt(unsigned int cbData, char *pbData);
156         pthread_t m_threadSend;
157         queues::MtQueue *m_pSendQueue;
158
159         CHEC SendDataRRInt(unsigned int cbData, char *pbData);
160         pthread_t m_threadReqRespSend;
161         queues::MtQueue *m_pReqRespSendQueue;
162
163     };
164
165 } // namespace network
166
167