5555#include < thread>
5656#include < map>
5757#include < utility>
58+ #include < optional>
5859
5960#include < fcntl.h>
6061#ifndef _MSC_VER
@@ -72,7 +73,13 @@ IE_CORE_DEFINERUNTIMETYPED( DisplayDriverServer );
7273namespace
7374{
7475
75- std::map<int , std::pair<DisplayDriverPtr, int >> mergeMap;
76+ struct MergeDriverInfo
77+ {
78+ DisplayDriverPtr mergeDriver = nullptr ;
79+ int mergeCount = 0 ;
80+ };
81+
82+ std::map<int , MergeDriverInfo> g_mergeMap;
7683
7784/* Set the FD_CLOEXEC flag for the given socket descriptor, so that it will not exist on child processes.*/
7885static void fixSocketFlags ( int socketDesc )
@@ -118,8 +125,7 @@ class DisplayDriverServer::Session : public RefCounted
118125 DisplayDriverPtr m_displayDriver;
119126 DisplayDriverServerHeader m_header;
120127 CharVectorDataPtr m_buffer;
121- bool m_mergeSession;
122- int m_mergeId;
128+ std::optional<int > m_mergeId;
123129};
124130
125131class DisplayDriverServer ::PrivateData : public RefCounted
@@ -299,7 +305,7 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session,
299305 */
300306
301307DisplayDriverServer::Session::Session ( boost::asio::io_service& io_service ) :
302- m_socket( io_service ), m_displayDriver(nullptr ), m_buffer( new CharVectorData( ) ), m_mergeSession( false ), m_mergeId(- 1 )
308+ m_socket( io_service ), m_displayDriver(nullptr ), m_buffer( new CharVectorData( ) )
303309{
304310}
305311
@@ -369,14 +375,18 @@ void DisplayDriverServer::Session::handleReadHeader( const boost::system::error_
369375 {
370376 try
371377 {
372- if ( !m_mergeSession )
378+ if ( !m_mergeId. has_value () )
373379 {
374380 m_displayDriver->imageClose ();
375381 }
376- else if ( auto search = mergeMap. find (m_mergeId); search != mergeMap. end () && --mergeMap[m_mergeId]. second <= 0 )
382+ else
377383 {
378- mergeMap.erase (m_mergeId);
379- m_displayDriver->imageClose ();
384+ auto &m = g_mergeMap.at (m_mergeId.value ()); // Error out if not found
385+ if ( --m.mergeCount <= 0 )
386+ {
387+ g_mergeMap.erase (m_mergeId.value ());
388+ m_displayDriver->imageClose ();
389+ }
380390 }
381391 }
382392 catch ( std::exception &e )
@@ -437,38 +447,31 @@ void DisplayDriverServer::Session::handleReadOpenParameters( const boost::system
437447
438448 const StringData *displayType = parameters->member <StringData>( " remoteDisplayType" , true /* throw if missing */ );
439449
440- const BoolData *mergeDriverData = parameters->member <BoolData>( " mergeDriver" , false );
441- m_mergeSession = mergeDriverData && mergeDriverData->readable ();
442-
443450 // create a displayDriver using the factory function.
444- if (!m_mergeSession )
451+ if ( !parameters-> member <IntData>( " displayDriverServer:mergeId " , false ) )
445452 {
446453 m_displayDriver = DisplayDriver::create ( displayType->readable (), displayWindow->readable (), dataWindow->readable (), channelNames->readable (), parameters );
447454 }
448455 else
449456 {
450- m_mergeId = parameters->member <IntData>( " sessionId " , true /* throw if missing */ )->readable ();
457+ m_mergeId = parameters->member <IntData>( " displayDriverServer:mergeId " , false /* throw if missing */ )->readable ();
451458
452459 // Check if merge ID in map, if not then create display driver and session count pair with merge ID.
453- if (const auto search = mergeMap.find (m_mergeId); search == mergeMap.end ())
460+ auto &m = g_mergeMap[m_mergeId.value ()];
461+ if ( !m.mergeDriver )
454462 {
455- const IntData *sessionClientsData = parameters->member <IntData>( " sessionClients" , true /* throw if missing */ );
456- mergeMap.emplace (
457- m_mergeId,
458- std::make_pair (
459- DisplayDriver::create (
460- displayType->readable (),
461- displayWindow->readable (),
462- displayWindow->readable (), // For merge we want dataWindow = displayWindow
463- channelNames->readable (),
464- parameters
465- ),
466- sessionClientsData->readable ()
467- )
463+ const IntData *sessionClientsData = parameters->member <IntData>( " displayDriverServer:mergeClients" , true /* throw if missing */ );
464+ m.mergeDriver = DisplayDriver::create (
465+ displayType->readable (),
466+ displayWindow->readable (),
467+ displayWindow->readable (), // For merge we want dataWindow = displayWindow
468+ channelNames->readable (),
469+ parameters
468470 );
471+ m.mergeCount = sessionClientsData->readable ();
469472 }
470473 // Merge ID is now in map, so load the display driver.
471- m_displayDriver = mergeMap[m_mergeId]. first ;
474+ m_displayDriver = m. mergeDriver ;
472475 }
473476 scanLineOrder = m_displayDriver->scanLineOrderOnly ();
474477 acceptsRepeatedData = m_displayDriver->acceptsRepeatedData ();
0 commit comments