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
25
26KINNG_REQUEST_SERVER::KINNG_REQUEST_SERVER( const std::string& aSocketUrl ) :
27 m_socketUrl( aSocketUrl ),
28 m_callback()
29{
30 Start();
31}
32
33
35{
36 Stop();
37}
38
39
41{
42 return m_thread.joinable();
43}
44
45
47{
48 m_shutdown.store( false );
49 m_thread = std::thread( [&]() { listenThread(); } );
50 return true;
51}
52
53
55{
56 if( !m_thread.joinable() )
57 return;
58
59 {
60 std::lock_guard<std::mutex> lock( m_mutex );
61 m_replyReady.notify_all();
62 }
63
64 m_shutdown.store( true );
65 m_thread.join();
66}
67
68
69void KINNG_REQUEST_SERVER::Reply( const std::string& aReply )
70{
71 std::lock_guard<std::mutex> lock( m_mutex );
72 m_pendingReply = aReply;
73 m_replyReady.notify_all();
74}
75
76
78{
79 nng_socket socket;
80 nng_listener listener;
81 int retCode = 0;
82
83 retCode = nng_rep0_open( &socket );
84
85 if( retCode != 0 )
86 return;
87
88 retCode = nng_listener_create( &listener, socket, m_socketUrl.c_str() );
89
90 if( retCode != 0 )
91 return;
92
93 nng_socket_set_ms( socket, NNG_OPT_RECVTIMEO, 500 );
94
95 nng_listener_start( listener, 0 );
96
97 while( !m_shutdown.load() )
98 {
99 char* buf = nullptr;
100 size_t sz;
101 uint64_t val;
102
103 retCode = nng_recv( socket, &buf, &sz, NNG_FLAG_ALLOC );
104
105 if( retCode == NNG_ETIMEDOUT )
106 continue;
107
108 if( retCode != 0 )
109 {
110 nng_free( buf, sz );
111 break;
112 }
113
114 std::string message( buf, sz );
115
116 if( m_callback )
117 m_callback( &message );
118
119 std::unique_lock<std::mutex> lock( m_mutex );
120 m_replyReady.wait( lock, [&]() { return !m_pendingReply.empty(); } );
121
122 retCode = nng_send( socket, const_cast<std::string::value_type*>( m_pendingReply.c_str() ),
123 m_pendingReply.length(), 0 );
124
125 m_pendingReply.clear();
126 }
127
128 nng_close( socket );
129}
bool Running() const
Definition: kinng.cpp:40
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:77
KINNG_REQUEST_SERVER(const std::string &aSocketUrl)
Definition: kinng.cpp:26
void Reply(const std::string &aReply)
Definition: kinng.cpp:69
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