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 (C) 2023 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 ),
36 m_callback()
37{
38 Start();
39}
40
41
43{
44 Stop();
45}
46
47
49{
50 return m_thread.joinable();
51}
52
53
55{
56 m_shutdown.store( false );
57 m_thread = std::thread( [&]() { listenThread(); } );
58 return true;
59}
60
61
63{
64 if( !m_thread.joinable() )
65 return;
66
67 {
68 std::lock_guard<std::mutex> lock( m_mutex );
69 m_replyReady.notify_all();
70 }
71
72 m_shutdown.store( true );
73 m_thread.join();
74}
75
76
77void KINNG_REQUEST_SERVER::Reply( const std::string& aReply )
78{
79 std::lock_guard<std::mutex> lock( m_mutex );
80 m_pendingReply = aReply;
81 m_replyReady.notify_all();
82}
83
84
86{
87 nng_socket socket;
88 nng_listener listener;
89 int retCode = 0;
90
91 wxLogTrace( TraceNng, wxS( "KINNG_REQUEST_SERVER starting" ) );
92
93 retCode = nng_rep0_open( &socket );
94
95 if( retCode != 0 )
96 {
97 wxLogTrace( TraceNng,
98 wxString::Format( wxS( "Got error code %d from nng_rep0_open!" ), retCode ) );
99 return;
100 }
101
102 retCode = nng_listener_create( &listener, socket, m_socketUrl.c_str() );
103
104 if( retCode != 0 )
105 {
106 wxLogTrace( TraceNng,
107 wxString::Format( wxS( "Got error code %d from nng_listener_create!" ),
108 retCode ) );
109 return;
110 }
111
112 nng_socket_set_ms( socket, NNG_OPT_RECVTIMEO, 500 );
113
114 nng_listener_start( listener, 0 );
115
116 wxLogTrace( TraceNng, wxS( "KINNG_REQUEST_SERVER listener has started" ) );
117
118 while( !m_shutdown.load() )
119 {
120 char* buf = nullptr;
121 size_t sz;
122 uint64_t val;
123
124 retCode = nng_recv( socket, &buf, &sz, NNG_FLAG_ALLOC );
125
126 if( retCode == NNG_ETIMEDOUT )
127 continue;
128
129 if( retCode != 0 )
130 {
131 nng_free( buf, sz );
132 wxLogTrace( TraceNng,
133 wxString::Format( wxS( "Got error code %d from nngc_recv!" ), retCode ) );
134 break;
135 }
136
137 std::string message( buf, sz );
138
139 if( m_callback )
140 m_callback( &message );
141
142 std::unique_lock<std::mutex> lock( m_mutex );
143 m_replyReady.wait( lock, [&]() { return !m_pendingReply.empty(); } );
144
145 retCode = nng_send( socket, const_cast<std::string::value_type*>( m_pendingReply.c_str() ),
146 m_pendingReply.length(), 0 );
147
148 if( retCode != 0 )
149 {
150 wxLogTrace( TraceNng,
151 wxString::Format( wxS( "Got error code %d from nng_send!" ), retCode ) );
152 }
153
154 m_pendingReply.clear();
155 }
156
157 wxLogTrace( TraceNng, wxS( "KINNG_REQUEST_SERVER shutting down" ) );
158
159 nng_close( socket );
160}
bool Running() const
Definition: kinng.cpp:48
std::string m_socketUrl
Definition: kinng.h:57
std::string m_pendingReply
Definition: kinng.h:61
std::mutex m_mutex
Definition: kinng.h:65
void listenThread()
Definition: kinng.cpp:85
KINNG_REQUEST_SERVER(const std::string &aSocketUrl)
Definition: kinng.cpp:34
void Reply(const std::string &aReply)
Definition: kinng.cpp:77
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:63
static const wxChar TraceNng[]
Trace nng server debug output.
Definition: kinng.cpp:31