Audacity 3.2.0
Public Member Functions | Private Attributes | List of all members
IPCServer::Impl Class Reference
Collaboration diagram for IPCServer::Impl:
[legend]

Public Member Functions

 Impl (IPCChannelStatusCallback &callback)
 
int GetConnectPort () const noexcept
 
 ~Impl ()
 

Private Attributes

bool mTryConnect {true}
 
std::mutex mSync
 
std::unique_ptr< BufferedIPCChannelmChannel
 
std::unique_ptr< std::thread > mConnectionRoutine
 
int mConnectPort {0}
 
socket_guard mListenSocket
 

Detailed Description

Definition at line 24 of file IPCServer.cpp.

Constructor & Destructor Documentation

◆ Impl()

IPCServer::Impl::Impl ( IPCChannelStatusCallback callback)
inline

Definition at line 35 of file IPCServer.cpp.

36 {
37 mListenSocket = socket_guard { socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) };
38 if(!mListenSocket)
39 throw std::runtime_error("cannot create socket");
40
41 sockaddr_in addrhint{};
42 addrhint.sin_family = AF_INET;
43 addrhint.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
44 addrhint.sin_port = htons(INADDR_ANY);
45
46 static const int yes { 1 };
47 if(setsockopt(*mListenSocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&yes), sizeof(yes)) == SOCKET_ERROR)
48 throw std::runtime_error("cannot configure listen socket");
49
50 if(bind(*mListenSocket, reinterpret_cast<const sockaddr*>(&addrhint), sizeof(addrhint)) == SOCKET_ERROR)
51 throw std::runtime_error("socket bind error");
52
53 if(listen(*mListenSocket, 1) == SOCKET_ERROR)
54 throw std::runtime_error("socket listen error");
55
56 sockaddr_in addr{};
57 socklen_t addr_len { sizeof (addr) };
58 if(getsockname(*mListenSocket, reinterpret_cast<sockaddr*>(&addr), &addr_len) == SOCKET_ERROR)
59 throw std::runtime_error("failed to get socket name");
60
61 mConnectPort = ntohs(addr.sin_port);
62
63 mChannel = std::make_unique<BufferedIPCChannel>();
64 mConnectionRoutine = std::make_unique<std::thread>([this, &callback]
65 {
66 socket_guard connfd;
67
68 while(true)
69 {
70 {
71 //combine flag check and internal state initialization within a single lock...
72
73 std::lock_guard lck {mSync};
74 if(!mTryConnect)
75 return;
76
77 if(connfd)
78 {
79 mListenSocket.reset();//do not need that any more
80 try
81 {
82 mChannel->StartConversation(connfd.release(), callback);
83 }
84 catch(...)
85 {
86 callback.OnConnectionError();
87 }
88 //initialization finished, we can leave now
89 break;
90 }
91 }
92
93 fd_set readfds, exceptfds;
94 FD_ZERO(&readfds);
95 FD_ZERO(&exceptfds);
96 FD_SET(*mListenSocket, &readfds);
97 FD_SET(*mListenSocket, &exceptfds);
98
99 auto ret = select(NFDS(*mListenSocket), &readfds, nullptr, &exceptfds, nullptr);
100 if(ret == 1)
101 {
102 connfd = socket_guard { accept(*mListenSocket, nullptr, nullptr) };
103 if(!connfd)
104 {
105 callback.OnConnectionError();
106 break;
107 }
108 //connection created, finish initialization during next loop iteration under guarded section
109 }
110 else//SOCKET_ERROR
111 {
112 callback.OnConnectionError();
113 break;
114 }
115 }
116 });
117 }
virtual void OnConnectionError() noexcept=0
Called when connection attempt fails.
socket_guard mListenSocket
Definition: IPCServer.cpp:32
std::mutex mSync
Definition: IPCServer.cpp:27
std::unique_ptr< BufferedIPCChannel > mChannel
Definition: IPCServer.cpp:28
std::unique_ptr< std::thread > mConnectionRoutine
Definition: IPCServer.cpp:29
RAII-style socket wrapper. Since socket is closed on wrapper destruction, initializing multiple guard...
Definition: socket_guard.h:24
void reset() noexcept
Closes the socket.
Definition: socket_guard.h:71
SOCKET release() noexcept
Returns the socket descriptor and releases ownership.
Definition: socket_guard.h:63
#define NFDS(x)
Definition: ipc-types.h:32
#define SOCKET_ERROR
Definition: ipc-types.h:29

References mChannel, mConnectionRoutine, mConnectPort, mListenSocket, mSync, mTryConnect, NFDS, IPCChannelStatusCallback::OnConnectionError(), socket_guard::release(), socket_guard::reset(), and SOCKET_ERROR.

Here is the call graph for this function:

◆ ~Impl()

IPCServer::Impl::~Impl ( )
inline

Definition at line 121 of file IPCServer.cpp.

122 {
123 {
124 std::lock_guard lck{mSync};
125 mTryConnect = false;
126 //this will also interrupt select in connection thread
128 mChannel.reset();
129 }
131 mConnectionRoutine->join();
132 }

References mChannel, mConnectionRoutine, mListenSocket, mSync, mTryConnect, and socket_guard::reset().

Here is the call graph for this function:

Member Function Documentation

◆ GetConnectPort()

int IPCServer::Impl::GetConnectPort ( ) const
inlinenoexcept

Definition at line 119 of file IPCServer.cpp.

119{ return mConnectPort; }

References mConnectPort.

Member Data Documentation

◆ mChannel

std::unique_ptr<BufferedIPCChannel> IPCServer::Impl::mChannel
private

Definition at line 28 of file IPCServer.cpp.

Referenced by Impl(), and ~Impl().

◆ mConnectionRoutine

std::unique_ptr<std::thread> IPCServer::Impl::mConnectionRoutine
private

Definition at line 29 of file IPCServer.cpp.

Referenced by Impl(), and ~Impl().

◆ mConnectPort

int IPCServer::Impl::mConnectPort {0}
private

Definition at line 30 of file IPCServer.cpp.

Referenced by GetConnectPort(), and Impl().

◆ mListenSocket

socket_guard IPCServer::Impl::mListenSocket
private

Definition at line 32 of file IPCServer.cpp.

Referenced by Impl(), and ~Impl().

◆ mSync

std::mutex IPCServer::Impl::mSync
private

Definition at line 27 of file IPCServer.cpp.

Referenced by Impl(), and ~Impl().

◆ mTryConnect

bool IPCServer::Impl::mTryConnect {true}
private

Definition at line 26 of file IPCServer.cpp.

Referenced by Impl(), and ~Impl().


The documentation for this class was generated from the following file: