KiCad PCB EDA Suite
Loading...
Searching...
No Matches
kinng.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <kinng.h>
22#include <nng/nng.h>
23#include <nng/protocol/reqrep0/rep.h>
24#include <wx/log.h>
25
26
31static const wxChar TraceNng[] = wxT( "KINNG" );
32
33
34KINNG_REQUEST_SERVER::KINNG_REQUEST_SERVER( const std::string& aSocketUrl ) :
35 m_socketUrl( aSocketUrl ),
37{
38}
39
40
45
46
48{
49 return m_thread.joinable();
50}
51
52
54{
55 if( m_thread.joinable() )
56 return true;
57
58 m_shutdown.store( false );
59 m_pendingReply.clear();
60 m_thread = std::thread( [&]() { listenThread(); } );
61 return true;
62}
63
64
66{
67 if( !m_thread.joinable() )
68 return;
69
70 {
71 std::lock_guard<std::mutex> lock( m_mutex );
72 m_replyReady.notify_all();
73 }
74
75 m_shutdown.store( true );
76 m_thread.join();
77}
78
79
80void KINNG_REQUEST_SERVER::Reply( const std::string& aReply )
81{
82 std::lock_guard<std::mutex> lock( m_mutex );
83 m_pendingReply = aReply;
84 m_replyReady.notify_all();
85}
86
87
89{
90 nng_socket socket;
91 nng_listener listener;
92 int retCode = 0;
93
94 wxLogTrace( TraceNng, wxS( "KINNG_REQUEST_SERVER starting" ) );
95
96 retCode = nng_rep0_open( &socket );
97
98 if( retCode != 0 )
99 {
100 wxLogTrace( TraceNng,
101 wxString::Format( wxS( "Got error code %d from nng_rep0_open!" ), retCode ) );
102 return;
103 }
104
105 retCode = nng_listener_create( &listener, socket, m_socketUrl.c_str() );
106
107 if( retCode != 0 )
108 {
109 wxLogTrace( TraceNng,
110 wxString::Format( wxS( "Got error code %d from nng_listener_create!" ),
111 retCode ) );
112 return;
113 }
114
115 nng_socket_set_ms( socket, NNG_OPT_RECVTIMEO, 500 );
116
117 retCode = nng_listener_start( listener, 0 );
118
119 if( retCode != 0 )
120 {
121 wxLogTrace( TraceNng,
122 wxString::Format( wxS( "Got error code %d from nng_listener_start!" ),
123 retCode ) );
124 nng_close( socket );
125 return;
126 }
127
128 wxLogTrace( TraceNng, wxS( "KINNG_REQUEST_SERVER listener has started" ) );
129
130 while( !m_shutdown.load() )
131 {
132 char* buf = nullptr;
133 size_t sz = 0;
134
135 retCode = nng_recv( socket, &buf, &sz, NNG_FLAG_ALLOC );
136
137 if( retCode == NNG_ETIMEDOUT )
138 continue;
139
140 if( retCode != 0 )
141 {
142 if( buf )
143 nng_free( buf, sz );
144
145 wxLogTrace( TraceNng,
146 wxString::Format( wxS( "Got error code %d from nngc_recv!" ), retCode ) );
147 break;
148 }
149
150 m_sharedMessage.assign( buf, sz );
151 nng_free( buf, sz );
152 buf = nullptr;
153
154 if( m_callback )
156
157 std::unique_lock<std::mutex> lock( m_mutex );
158 m_replyReady.wait( lock, [&]() { return m_shutdown.load() || !m_pendingReply.empty(); } );
159
160 if( m_shutdown.load() )
161 break;
162
163 retCode = nng_send( socket, const_cast<std::string::value_type*>( m_pendingReply.c_str() ),
164 m_pendingReply.length(), 0 );
165
166 if( retCode != 0 )
167 {
168 wxLogTrace( TraceNng,
169 wxString::Format( wxS( "Got error code %d from nng_send!" ), retCode ) );
170 }
171 m_pendingReply.clear();
172 }
173
174 wxLogTrace( TraceNng, wxS( "KINNG_REQUEST_SERVER shutting down" ) );
175
176 nng_close( socket );
177}
bool Running() const
Definition kinng.cpp:47
std::string m_socketUrl
Definition kinng.h:57
std::string m_pendingReply
Definition kinng.h:63
std::mutex m_mutex
Definition kinng.h:67
KINNG_REQUEST_SERVER(const std::string &aSocketUrl)
Definition kinng.cpp:34
void Reply(const std::string &aReply)
Definition kinng.cpp:80
std::string m_sharedMessage
Definition kinng.h:61
std::function< void(std::string *)> m_callback
Definition kinng.h:59
std::thread m_thread
Definition kinng.h:53
std::atomic< bool > m_shutdown
Definition kinng.h:55
std::condition_variable m_replyReady
Definition kinng.h:65
static const wxChar TraceNng[]
Trace nng server debug output.
Definition kinng.cpp:31