Usermode/AxWin4 - Debugging quirks in ARCH=native
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / CIPCChannel_AcessIPCPipe.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * CIPCChannel_AcessIPCPipe.cpp
6  * - IPC Channel :: Acess' IPC Pipe /Devices/ipcpipe/<name>
7  */
8 #include <ipc.hpp>
9 #include <CIPCChannel_AcessIPCPipe.hpp>
10 #include <cerrno>
11 #include <system_error>
12 #include <acess/sys.h>
13 #include <algorithm>
14
15 namespace AxWin {
16
17 CIPCChannel_AcessIPCPipe::CIPCChannel_AcessIPCPipe(const ::std::string& suffix)
18 {
19         ::std::string   path = "/Devices/ipcpipe/" + suffix;
20         m_fd = _SysOpen(path.c_str(), OPENFLAG_CREATE);
21         if(m_fd == -1) {
22                 _SysDebug("Failed to open %s: %s", path.c_str(), strerror(errno));
23                 throw ::std::system_error(errno, ::std::system_category());
24         }
25 }
26 CIPCChannel_AcessIPCPipe::~CIPCChannel_AcessIPCPipe()
27 {
28         _SysClose(m_fd);
29 }
30
31 int CIPCChannel_AcessIPCPipe::FillSelect(fd_set& rfds)
32 {
33          int    maxfd = m_fd;
34         FD_SET(m_fd, &rfds);
35         
36         for( auto& clientref : m_clients )
37         {
38                 maxfd = ::std::max(maxfd, clientref.m_fd);
39                 FD_SET(clientref.m_fd, &rfds);
40         }
41         
42         return maxfd+1;
43 }
44
45 void CIPCChannel_AcessIPCPipe::HandleSelect(const fd_set& rfds)
46 {
47         if( FD_ISSET(m_fd, &rfds) )
48         {
49                 int newfd = _SysOpenChild(m_fd, "newclient", OPENFLAG_READ|OPENFLAG_WRITE);
50                 if( newfd == -1 ) {
51                         _SysDebug("ERROR - Failure to open new client on FD%i", m_fd);
52                 }
53                 else {
54                         _SysDebug("CIPCChannel_AcessIPCPipe::HandleSelect - New client on FD %i with FD%i",
55                                 m_fd, newfd);
56                         
57                         // emplace creates a new object within the list
58                         m_clients.emplace( m_clients.end(), *this, newfd );
59                         IPC::RegisterClient( m_clients.back() );
60                 }
61         }
62
63         for( auto it = m_clients.begin(); it != m_clients.end();  )
64         {
65                 CClient_AcessIPCPipe& clientref = *it;
66                 ++ it;
67                 
68                 if( FD_ISSET(clientref.m_fd, &rfds) )
69                 {
70                         try {
71                                 clientref.HandleReceive();
72                         }
73                         catch( const ::std::exception& e ) {
74                                 _SysDebug("ERROR - Exception processing IPCPipe FD%i: '%s', removing",
75                                         clientref.m_fd, e.what()
76                                         );
77                                 it = m_clients.erase(--it);
78                         }
79                 }
80         }
81 }
82
83
84 CClient_AcessIPCPipe::CClient_AcessIPCPipe(::AxWin::IIPCChannel& channel, int fd):
85         CClient(channel),
86         m_fd(fd)
87 {
88 }
89
90 CClient_AcessIPCPipe::~CClient_AcessIPCPipe()
91 {
92         _SysClose(m_fd);
93         _SysDebug("Closed client FD%i", m_fd);
94 }
95
96 void CClient_AcessIPCPipe::SendMessage(CSerialiser& message)
97 {
98         const ::std::vector<uint8_t>&   data = message.Compact();
99         
100         _SysDebug("CClient_AcessIPCPipe::SendMessage - %i bytes to %i", data.size(), m_fd);
101         //_SysDebugHex("CClient_AcessIPCPipe::SendMessage", data.data(), data.size());
102         _SysWrite(m_fd, data.data(), data.size());
103 }
104
105 void CClient_AcessIPCPipe::HandleReceive()
106 {
107         ::std::vector<uint8_t>  rxbuf(0x1000);
108         size_t len = _SysRead(m_fd, rxbuf.data(), rxbuf.capacity());
109         if( len == (size_t)-1 )
110                 throw ::std::system_error(errno, ::std::system_category());
111         //_SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
112         _SysDebugHex("CClient_AcessIPCPipe::HandleReceive", rxbuf.data(), len);
113         rxbuf.resize(len);
114         
115         CDeserialiser   msg( ::std::move(rxbuf) );
116         CClient::HandleMessage( msg );
117 }
118
119 };
120

UCC git Repository :: git.ucc.asn.au