53
53
#include " boost/bind/bind.hpp"
54
54
55
55
#include < thread>
56
+ #include < map>
57
+ #include < utility>
58
+ #include < optional>
56
59
57
60
#include < fcntl.h>
58
61
#ifndef _MSC_VER
@@ -70,6 +73,14 @@ IE_CORE_DEFINERUNTIMETYPED( DisplayDriverServer );
70
73
namespace
71
74
{
72
75
76
+ struct MergeDriverInfo
77
+ {
78
+ DisplayDriverPtr mergeDriver = nullptr ;
79
+ int mergeCount = 0 ;
80
+ };
81
+
82
+ using MergeMap = std::map<int , MergeDriverInfo>;
83
+
73
84
/* Set the FD_CLOEXEC flag for the given socket descriptor, so that it will not exist on child processes.*/
74
85
static void fixSocketFlags ( int socketDesc )
75
86
{
@@ -95,7 +106,7 @@ class DisplayDriverServer::Session : public RefCounted
95
106
{
96
107
public:
97
108
98
- Session ( boost::asio::io_service& io_service );
109
+ Session ( boost::asio::io_service& io_service, MergeMap& mergeMap );
99
110
~Session () override ;
100
111
101
112
boost::asio::ip::tcp::socket& socket ();
@@ -114,6 +125,8 @@ class DisplayDriverServer::Session : public RefCounted
114
125
DisplayDriverPtr m_displayDriver;
115
126
DisplayDriverServerHeader m_header;
116
127
CharVectorDataPtr m_buffer;
128
+ MergeMap& m_mergeMap;
129
+ std::optional<int > m_mergeId;
117
130
};
118
131
119
132
class DisplayDriverServer ::PrivateData : public RefCounted
@@ -125,6 +138,7 @@ class DisplayDriverServer::PrivateData : public RefCounted
125
138
boost::asio::io_service m_service;
126
139
boost::asio::ip::tcp::acceptor m_acceptor;
127
140
std::thread m_thread;
141
+ MergeMap m_mergeMap;
128
142
129
143
PrivateData ( DisplayDriverServer::Port portNumber ) :
130
144
m_service (),
@@ -196,7 +210,7 @@ DisplayDriverServer::DisplayDriverServer( DisplayDriverServer::Port portNumber )
196
210
{
197
211
m_data = new DisplayDriverServer::PrivateData ( portNumber );
198
212
199
- DisplayDriverServer::SessionPtr newSession ( new DisplayDriverServer::Session ( m_data->m_service ) );
213
+ DisplayDriverServer::SessionPtr newSession ( new DisplayDriverServer::Session ( m_data->m_service , m_data-> m_mergeMap ) );
200
214
m_data->m_acceptor .async_accept ( newSession->socket (),
201
215
boost::bind ( &DisplayDriverServer::handleAccept, this , newSession,
202
216
boost::asio::placeholders::error));
@@ -280,7 +294,7 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session,
280
294
{
281
295
if (!error)
282
296
{
283
- DisplayDriverServer::SessionPtr newSession ( new DisplayDriverServer::Session ( m_data->m_service ) );
297
+ DisplayDriverServer::SessionPtr newSession ( new DisplayDriverServer::Session ( m_data->m_service , m_data-> m_mergeMap ) );
284
298
m_data->m_acceptor .async_accept ( newSession->socket (),
285
299
boost::bind ( &DisplayDriverServer::handleAccept, this , newSession,
286
300
boost::asio::placeholders::error));
@@ -292,8 +306,8 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session,
292
306
* DisplayDriverServer::Session functions
293
307
*/
294
308
295
- DisplayDriverServer::Session::Session ( boost::asio::io_service& io_service ) :
296
- m_socket( io_service ), m_displayDriver(nullptr ), m_buffer( new CharVectorData( ) )
309
+ DisplayDriverServer::Session::Session ( boost::asio::io_service& io_service, MergeMap& mergeMap ) :
310
+ m_socket( io_service ), m_displayDriver(nullptr ), m_buffer( new CharVectorData( ) ), m_mergeMap( mergeMap )
297
311
{
298
312
}
299
313
@@ -363,7 +377,19 @@ void DisplayDriverServer::Session::handleReadHeader( const boost::system::error_
363
377
{
364
378
try
365
379
{
366
- m_displayDriver->imageClose ();
380
+ if ( !m_mergeId.has_value () )
381
+ {
382
+ m_displayDriver->imageClose ();
383
+ }
384
+ else
385
+ {
386
+ auto &m = m_mergeMap.at (m_mergeId.value ()); // Error out if not found
387
+ if ( --m.mergeCount <= 0 )
388
+ {
389
+ m_mergeMap.erase (m_mergeId.value ());
390
+ m_displayDriver->imageClose ();
391
+ }
392
+ }
367
393
}
368
394
catch ( std::exception &e )
369
395
{
@@ -424,8 +450,31 @@ void DisplayDriverServer::Session::handleReadOpenParameters( const boost::system
424
450
const StringData *displayType = parameters->member <StringData>( " remoteDisplayType" , true /* throw if missing */ );
425
451
426
452
// create a displayDriver using the factory function.
427
- m_displayDriver = DisplayDriver::create ( displayType->readable (), displayWindow->readable (), dataWindow->readable (), channelNames->readable (), parameters );
453
+ if ( !parameters->member <IntData>( " displayDriverServer:mergeId" , false ) )
454
+ {
455
+ m_displayDriver = DisplayDriver::create ( displayType->readable (), displayWindow->readable (), dataWindow->readable (), channelNames->readable (), parameters );
456
+ }
457
+ else
458
+ {
459
+ m_mergeId = parameters->member <IntData>( " displayDriverServer:mergeId" , false /* throw if missing */ )->readable ();
428
460
461
+ // Check if merge ID in map, if not then create display driver and session count pair with merge ID.
462
+ auto &m = m_mergeMap[m_mergeId.value ()];
463
+ if ( !m.mergeDriver )
464
+ {
465
+ const IntData *sessionClientsData = parameters->member <IntData>( " displayDriverServer:mergeClients" , true /* throw if missing */ );
466
+ m.mergeDriver = DisplayDriver::create (
467
+ displayType->readable (),
468
+ displayWindow->readable (),
469
+ displayWindow->readable (), // For merge we want dataWindow = displayWindow
470
+ channelNames->readable (),
471
+ parameters
472
+ );
473
+ m.mergeCount = sessionClientsData->readable ();
474
+ }
475
+ // Merge ID is now in map, so load the display driver.
476
+ m_displayDriver = m.mergeDriver ;
477
+ }
429
478
scanLineOrder = m_displayDriver->scanLineOrderOnly ();
430
479
acceptsRepeatedData = m_displayDriver->acceptsRepeatedData ();
431
480
}
0 commit comments