Merge pull request #2739 from jasp00/sync-socket
Synchronize with remote plugins using local sockets
This commit is contained in:
@@ -40,6 +40,12 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef SYNC_WITH_SHM_FIFO
|
||||
#include <QtCore/QUuid>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
|
||||
// simple helper thread monitoring our RemotePlugin - if process terminates
|
||||
// unexpectedly invalidate plugin so LMMS doesn't lock up
|
||||
@@ -70,7 +76,12 @@ void ProcessWatcher::run()
|
||||
|
||||
|
||||
RemotePlugin::RemotePlugin() :
|
||||
QObject(),
|
||||
#ifdef SYNC_WITH_SHM_FIFO
|
||||
RemotePluginBase( new shmFifo(), new shmFifo() ),
|
||||
#else
|
||||
RemotePluginBase(),
|
||||
#endif
|
||||
m_failed( true ),
|
||||
m_process(),
|
||||
m_watcher( this ),
|
||||
@@ -86,6 +97,34 @@ RemotePlugin::RemotePlugin() :
|
||||
m_inputCount( DEFAULT_CHANNELS ),
|
||||
m_outputCount( DEFAULT_CHANNELS )
|
||||
{
|
||||
#ifndef SYNC_WITH_SHM_FIFO
|
||||
struct sockaddr_un sa;
|
||||
sa.sun_family = AF_LOCAL;
|
||||
|
||||
m_socketFile = QDir::tempPath() + QDir::separator() +
|
||||
QUuid::createUuid().toString();
|
||||
const char * path = m_socketFile.toUtf8().constData();
|
||||
size_t length = strlen( path );
|
||||
if ( length >= sizeof sa.sun_path )
|
||||
{
|
||||
length = sizeof sa.sun_path - 1;
|
||||
qWarning( "Socket path too long." );
|
||||
}
|
||||
memcpy( sa.sun_path, path, length );
|
||||
sa.sun_path[length] = '\0';
|
||||
|
||||
m_server = socket( PF_LOCAL, SOCK_STREAM, 0 );
|
||||
if ( m_server == -1 )
|
||||
{
|
||||
qWarning( "Unable to start the server." );
|
||||
}
|
||||
remove( path );
|
||||
int ret = bind( m_server, (struct sockaddr *) &sa, sizeof sa );
|
||||
if ( ret == -1 || listen( m_server, 1 ) == -1 )
|
||||
{
|
||||
qWarning( "Unable to start the server." );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +156,14 @@ RemotePlugin::~RemotePlugin()
|
||||
shmctl( m_shmID, IPC_RMID, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SYNC_WITH_SHM_FIFO
|
||||
if ( close( m_server ) == -1)
|
||||
{
|
||||
qWarning( "Error freeing resources." );
|
||||
}
|
||||
remove( m_socketFile.toUtf8().constData() );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -128,15 +175,36 @@ bool RemotePlugin::init( const QString &pluginExecutable,
|
||||
lock();
|
||||
if( m_failed )
|
||||
{
|
||||
#ifdef SYNC_WITH_SHM_FIFO
|
||||
reset( new shmFifo(), new shmFifo() );
|
||||
#endif
|
||||
m_failed = false;
|
||||
}
|
||||
QString exec = QFileInfo(QDir("plugins:"), pluginExecutable).absoluteFilePath();
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
if( ! exec.endsWith( ".exe", Qt::CaseInsensitive ) )
|
||||
{
|
||||
exec += ".exe";
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ! QFile( exec ).exists() )
|
||||
{
|
||||
qWarning( "Remote plugin '%s' not found.",
|
||||
exec.toUtf8().constData() );
|
||||
m_failed = true;
|
||||
unlock();
|
||||
return failed();
|
||||
}
|
||||
|
||||
QStringList args;
|
||||
#ifdef SYNC_WITH_SHM_FIFO
|
||||
// swap in and out for bidirectional communication
|
||||
args << QString::number( out()->shmKey() );
|
||||
args << QString::number( in()->shmKey() );
|
||||
#else
|
||||
args << m_socketFile;
|
||||
#endif
|
||||
#ifndef DEBUG_REMOTE_PLUGIN
|
||||
m_process.setProcessChannelMode( QProcess::ForwardedChannels );
|
||||
m_process.setWorkingDirectory( QCoreApplication::applicationDirPath() );
|
||||
@@ -146,6 +214,33 @@ bool RemotePlugin::init( const QString &pluginExecutable,
|
||||
qDebug() << exec << args;
|
||||
#endif
|
||||
|
||||
connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ),
|
||||
this, SLOT( processFinished( int, QProcess::ExitStatus ) ) );
|
||||
|
||||
#ifndef SYNC_WITH_SHM_FIFO
|
||||
struct pollfd pollin;
|
||||
pollin.fd = m_server;
|
||||
pollin.events = POLLIN;
|
||||
|
||||
switch ( poll( &pollin, 1, 30000 ) )
|
||||
{
|
||||
case -1:
|
||||
qWarning( "Unexpected poll error." );
|
||||
break;
|
||||
|
||||
case 0:
|
||||
qWarning( "Remote plugin did not connect." );
|
||||
break;
|
||||
|
||||
default:
|
||||
m_socket = accept( m_server, NULL, NULL );
|
||||
if ( m_socket == -1 )
|
||||
{
|
||||
qWarning( "Unexpected socket error." );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
resizeSharedProcessingMemory();
|
||||
|
||||
if( waitForInitDoneMsg )
|
||||
@@ -337,6 +432,17 @@ void RemotePlugin::resizeSharedProcessingMemory()
|
||||
|
||||
|
||||
|
||||
void RemotePlugin::processFinished( int exitCode,
|
||||
QProcess::ExitStatus exitStatus )
|
||||
{
|
||||
#ifndef SYNC_WITH_SHM_FIFO
|
||||
invalidate();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool RemotePlugin::processMessage( const message & _m )
|
||||
{
|
||||
lock();
|
||||
@@ -345,6 +451,7 @@ bool RemotePlugin::processMessage( const message & _m )
|
||||
switch( _m.id )
|
||||
{
|
||||
case IdUndefined:
|
||||
unlock();
|
||||
return false;
|
||||
|
||||
case IdInitDone:
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "MemoryManager.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "NotePlayHandle.h"
|
||||
@@ -611,6 +613,20 @@ int main( int argc, char * * argv )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
if ( sigemptyset( &sa.sa_mask ) )
|
||||
{
|
||||
fprintf( stderr, "Signal initialization failed.\n" );
|
||||
}
|
||||
if ( sigaction( SIGPIPE, &sa, NULL ) )
|
||||
{
|
||||
fprintf( stderr, "Signal initialization failed.\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// if we have an output file for rendering, just render the song
|
||||
// without starting the GUI
|
||||
if( !renderOut.isEmpty() )
|
||||
|
||||
Reference in New Issue
Block a user