228 {
229
230 critical_region cr_invoke(m_invoke_lock);
231
232 boost::interprocess::ipcdetail::atomic_write32(&m_invoke_is_active, 1);
233 boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 0);
234 misc_utils::destr_ptr hdlr = misc_utils::add_exit_scope_handler(boost::bind(&levin_duplex_client::on_leave_invoke, this));
235
237
240
241
242 bucket_head
head = {0};
244 head.m_cb = in_buff.size();
245 head.m_have_to_return_data =
true;
247#ifdef TRACE_LEVIN_PACKETS_BY_GUIDS
248 ::UuidCreate(&
head.m_id);
249#endif
250 head.m_command = command;
253 LOG_PRINT("[" << m_socket <<"] Sending invoke data", LOG_LEVEL_4);
254
257 int res = ::send(m_socket, (
const char*)&
head,
sizeof(
head), 0);
258 if(SOCKET_ERROR ==
res)
259 {
260 int err = ::WSAGetLastError();
261 LOG_ERROR(
"Failed to send(), err = " << err <<
" \"" << socket_errors::get_socket_error_text(err) <<
"\"");
264 }
265 LOG_PRINT_L4(
"[" << m_socket <<
"] SEND " << (
int)in_buff.size());
266 res = ::send(m_socket, in_buff.data(), (
int)in_buff.size(), 0);
267 if(SOCKET_ERROR ==
res)
268 {
269 int err = ::WSAGetLastError();
270 LOG_ERROR(
"Failed to send(), err = " << err <<
" \"" << socket_errors::get_socket_error_text(err) <<
"\"");
273 }
275 LOG_PRINT_L4(
"LEVIN_PACKET_SENT. [len=" <<
head.m_cb <<
", flags=" <<
head.m_flags <<
", is_cmd=" <<
head.m_have_to_return_data <<
", cmd_id = " <<
head.m_command <<
", pr_v=" <<
head.m_protocol_version <<
", uid=" << string_tools::get_str_from_guid_a(
head.m_id) <<
"]");
276
277
278 boost::system_time timeout = boost::get_system_time()+ boost::posix_time::milliseconds(100);
279 size_t timeout_count = 0;
280 boost::unique_lock<boost::mutex> lock(m_invoke_event);
281
282 while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_data_ready))
283 {
284 if(!m_invoke_cond.timed_wait(lock, timeout))
285 {
286 if(timeout_count < 10)
287 {
288
289 timeout = boost::get_system_time()+ boost::posix_time::milliseconds(100);
290 ++timeout_count;
291 continue;
292 }else if(timeout_count == 10)
293 {
294
295 timeout = boost::get_system_time()+ boost::posix_time::minutes(10);
296 ++timeout_count;
297 continue;
298 }else
299 {
300 LOG_PRINT("[" << m_socket <<"] Timeout on waiting invoke result. ", LOG_LEVEL_0);
301
303 }
304 }
305 }
306
307
309 buff_out.swap(m_local_invoke_buff);
310 m_local_invoke_buff.clear();
312 return m_invoke_res;
313 }
#define LEVIN_PROTOCOL_VER_1
#define LEVIN_PACKET_REQUEST
#define LEVIN_ERROR_CONNECTION_TIMEDOUT