mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-22 15:38:02 +02:00
Fix startup hangs when opening multiple files on Linux and Mac.
Seem there's either a critter in the wx2812 socket IPC code (the socket processing was rewritten for the wx3 series) that could cause Audacity to hang during startup if more than 1 file was opened at the same time. It was hit or miss, but more hit than miss and was likely to occur when opening multiple files in a file manager. This fix was to stop using the wx2 IPC code and craft our own basic startup messaging.
This commit is contained in:
parent
945e68ba89
commit
cdde320f0d
@ -53,6 +53,7 @@ It handles initialization and termination by subclassing wxApp.
|
|||||||
// chmod, lstat, geteuid
|
// chmod, lstat, geteuid
|
||||||
#ifdef __UNIX__
|
#ifdef __UNIX__
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/file.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -679,12 +680,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
|
||||||
|
|
||||||
// Where drag/drop or "Open With" filenames get stored until
|
// Where drag/drop or "Open With" filenames get stored until
|
||||||
// the timer routine gets around to picking them up.
|
// the timer routine gets around to picking them up.
|
||||||
static wxArrayString ofqueue;
|
static wxArrayString ofqueue;
|
||||||
|
|
||||||
|
#ifdef __WXMAC__
|
||||||
|
|
||||||
// in response of an open-document apple event
|
// in response of an open-document apple event
|
||||||
void AudacityApp::MacOpenFile(const wxString &fileName)
|
void AudacityApp::MacOpenFile(const wxString &fileName)
|
||||||
{
|
{
|
||||||
@ -719,6 +720,10 @@ typedef int (AudacityApp::*SPECIALKEYEVENT)(wxKeyEvent&);
|
|||||||
#define ID_RECENT_FIRST 6101
|
#define ID_RECENT_FIRST 6101
|
||||||
#define ID_RECENT_LAST 6112
|
#define ID_RECENT_LAST 6112
|
||||||
|
|
||||||
|
// IPC communication
|
||||||
|
#define ID_IPC_SERVER 6200
|
||||||
|
#define ID_IPC_SOCKET 6201
|
||||||
|
|
||||||
// we don't really care about the timer id, but set this value just in case we do in the future
|
// we don't really care about the timer id, but set this value just in case we do in the future
|
||||||
#define kAudacityAppTimerID 0
|
#define kAudacityAppTimerID 0
|
||||||
|
|
||||||
@ -736,6 +741,12 @@ BEGIN_EVENT_TABLE(AudacityApp, wxApp)
|
|||||||
EVT_MENU(wxID_PREFERENCES, AudacityApp::OnMenuPreferences)
|
EVT_MENU(wxID_PREFERENCES, AudacityApp::OnMenuPreferences)
|
||||||
EVT_MENU(wxID_EXIT, AudacityApp::OnMenuExit)
|
EVT_MENU(wxID_EXIT, AudacityApp::OnMenuExit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __WXMSW__
|
||||||
|
EVT_SOCKET(ID_IPC_SERVER, AudacityApp::OnServerEvent)
|
||||||
|
EVT_SOCKET(ID_IPC_SOCKET, AudacityApp::OnSocketEvent)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Recent file event handlers.
|
// Recent file event handlers.
|
||||||
EVT_MENU(ID_RECENT_CLEAR, AudacityApp::OnMRUClear)
|
EVT_MENU(ID_RECENT_CLEAR, AudacityApp::OnMRUClear)
|
||||||
EVT_MENU_RANGE(ID_RECENT_FIRST, ID_RECENT_LAST, AudacityApp::OnMRUFile)
|
EVT_MENU_RANGE(ID_RECENT_FIRST, ID_RECENT_LAST, AudacityApp::OnMRUFile)
|
||||||
@ -821,27 +832,36 @@ void AudacityApp::OnMRUFile(wxCommandEvent& event) {
|
|||||||
|
|
||||||
void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event))
|
void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
#if defined(__WXMAC__)
|
|
||||||
// Filenames are queued when Audacity receives the a few of the
|
// Filenames are queued when Audacity receives the a few of the
|
||||||
// AppleEvent messages (via wxWidgets). So, open any that are
|
// AppleEvent messages (via wxWidgets). So, open any that are
|
||||||
// in the queue and clean the queue.
|
// in the queue and clean the queue.
|
||||||
if (ofqueue.GetCount()) {
|
if (gInited) {
|
||||||
// Load each file on the queue
|
if (ofqueue.GetCount()) {
|
||||||
while (ofqueue.GetCount()) {
|
// Load each file on the queue
|
||||||
wxString name(ofqueue[0]);
|
while (ofqueue.GetCount()) {
|
||||||
ofqueue.RemoveAt(0);
|
wxString name(ofqueue[0]);
|
||||||
// TODO: Handle failures better.
|
ofqueue.RemoveAt(0);
|
||||||
// Some failures are OK, e.g. file not found, just would-be-nices to do better,
|
|
||||||
// so FAIL_MSG is more a case of an enhancement request than an actual problem.
|
// Get the user's attention if no file name was specified
|
||||||
// LL: In all but one case an appropriate message is already displayed. The
|
if (name.IsEmpty()) {
|
||||||
// instance that a message is NOT displayed is when a failure to write
|
// Get the users attention
|
||||||
// to the config file has occurred.
|
GetActiveProject()->Raise();
|
||||||
if (!MRUOpen(name)) {
|
GetActiveProject()->RequestUserAttention();
|
||||||
wxFAIL_MSG(wxT("MRUOpen failed"));
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Handle failures better.
|
||||||
|
// Some failures are OK, e.g. file not found, just would-be-nices to do better,
|
||||||
|
// so FAIL_MSG is more a case of an enhancement request than an actual problem.
|
||||||
|
// LL: In all but one case an appropriate message is already displayed. The
|
||||||
|
// instance that a message is NOT displayed is when a failure to write
|
||||||
|
// to the config file has occurred.
|
||||||
|
if (!MRUOpen(name)) {
|
||||||
|
wxFAIL_MSG(wxT("MRUOpen failed"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check if a warning for missing aliased files should be displayed
|
// Check if a warning for missing aliased files should be displayed
|
||||||
if (ShouldShowMissingAliasedFileWarning()) {
|
if (ShouldShowMissingAliasedFileWarning()) {
|
||||||
@ -1027,6 +1047,9 @@ bool AudacityApp::OnInit()
|
|||||||
m_aliasMissingWarningShouldShow = true;
|
m_aliasMissingWarningShouldShow = true;
|
||||||
m_LastMissingBlockFile = NULL;
|
m_LastMissingBlockFile = NULL;
|
||||||
|
|
||||||
|
mChecker = NULL;
|
||||||
|
mIPCServ = NULL;
|
||||||
|
|
||||||
#if defined(__WXGTK__)
|
#if defined(__WXGTK__)
|
||||||
// Workaround for bug 154 -- initialize to false
|
// Workaround for bug 154 -- initialize to false
|
||||||
inKbdHandler = false;
|
inKbdHandler = false;
|
||||||
@ -1203,6 +1226,7 @@ bool AudacityApp::OnInit()
|
|||||||
#if !wxCHECK_VERSION(3, 0, 0)
|
#if !wxCHECK_VERSION(3, 0, 0)
|
||||||
FinishInits();
|
FinishInits();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1576,107 +1600,237 @@ bool AudacityApp::InitTempDir()
|
|||||||
bool AudacityApp::CreateSingleInstanceChecker()
|
bool AudacityApp::CreateSingleInstanceChecker()
|
||||||
{
|
{
|
||||||
wxString name = wxString(wxT(".")) + IPC_APPL;
|
wxString name = wxString(wxT(".")) + IPC_APPL;
|
||||||
mChecker = new wxSingleInstanceChecker();
|
|
||||||
|
|
||||||
wxString appl = IPC_APPL;
|
|
||||||
|
|
||||||
#if defined(__WXGTK__) || defined(__WXMAC__)
|
|
||||||
appl = wxGetHomeDir() + wxT("/") + name + wxT(".sock");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
wxString runningTwoCopiesStr = _("Running two copies of Audacity simultaneously may cause\ndata loss or cause your system to crash.\n\n");
|
wxString runningTwoCopiesStr = _("Running two copies of Audacity simultaneously may cause\ndata loss or cause your system to crash.\n\n");
|
||||||
|
bool success;
|
||||||
|
|
||||||
if (!mChecker->Create(name + wxT(".lock"), wxGetHomeDir())) {
|
mChecker = new wxSingleInstanceChecker();
|
||||||
|
success = mChecker->Create(name + wxT(".lock"), wxGetHomeDir());
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
// Error initializing the wxSingleInstanceChecker. We don't know
|
// Error initializing the wxSingleInstanceChecker. We don't know
|
||||||
// whether there is another instance running or not.
|
// whether there is another instance running or not.
|
||||||
|
|
||||||
wxString prompt =
|
wxString prompt =
|
||||||
_("Audacity was not able to lock the temporary files directory.\nThis folder may be in use by another copy of Audacity.\n") +
|
_("Audacity was not able to obtain lock the temporary files directory.\nThis folder may be in use by another copy of Audacity.\n") +
|
||||||
runningTwoCopiesStr +
|
runningTwoCopiesStr +
|
||||||
_("Do you still want to start Audacity?");
|
_("Do you still want to start Audacity?");
|
||||||
int action = wxMessageBox(prompt,
|
int action = wxMessageBox(prompt,
|
||||||
_("Error Locking Temporary Folder"),
|
_("Error Locking Temporary Folder"),
|
||||||
wxYES_NO | wxICON_EXCLAMATION,
|
wxYES_NO | wxICON_EXCLAMATION,
|
||||||
NULL);
|
NULL);
|
||||||
if (action == wxNO) {
|
if (action == wxNO)
|
||||||
delete mChecker;
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( mChecker->IsAnotherRunning() ) {
|
|
||||||
// Get the 1st argument (filename) if there is one.
|
#if defined(__UNIX__)
|
||||||
wxString cmd;
|
wxString sockFile(wxGetHomeDir() + wxT("/") + name + wxT(".sock"));
|
||||||
if (argc > 1) {
|
#endif
|
||||||
cmd = argv[1];
|
|
||||||
|
// Is this process the first one?
|
||||||
|
if (!mChecker->IsAnotherRunning())
|
||||||
|
{
|
||||||
|
#if defined(__WXMSW__)
|
||||||
|
// Create the DDE IPC server
|
||||||
|
mIPCServ = new IPCServ(IPC_APPL);
|
||||||
|
#else
|
||||||
|
int mask = umask(077);
|
||||||
|
remove(OSFILENAME(sockFile));
|
||||||
|
wxUNIXaddress addr;
|
||||||
|
addr.Filename(sockFile);
|
||||||
|
mIPCServ = new wxSocketServer(addr, wxSOCKET_NOWAIT);
|
||||||
|
umask(mask);
|
||||||
|
|
||||||
|
if (!mIPCServ || !mIPCServ->IsOk())
|
||||||
|
{
|
||||||
|
// TODO: Complain here
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
mIPCServ->SetEventHandler(*this, ID_IPC_SERVER);
|
||||||
// On Windows and Linux, we attempt to make a connection
|
mIPCServ->SetNotify(wxSOCKET_CONNECTION_FLAG);
|
||||||
// to an already active Audacity. If successful, we send
|
mIPCServ->Notify(true);
|
||||||
// the first command line argument (the audio file name)
|
#endif
|
||||||
// to that Audacity for processing.
|
return true;
|
||||||
wxClient client;
|
|
||||||
wxConnectionBase *conn;
|
|
||||||
|
|
||||||
// We try up to 50 times since there's a small window
|
|
||||||
// where the DDE server on Windows may not have been fully
|
|
||||||
// initialized.
|
|
||||||
for (int i = 0; i < 50; i++) {
|
|
||||||
conn = client.MakeConnection(wxEmptyString,
|
|
||||||
appl,
|
|
||||||
IPC_TOPIC);
|
|
||||||
if (conn) {
|
|
||||||
bool ok = conn->Execute(cmd);
|
|
||||||
|
|
||||||
conn->Disconnect();
|
|
||||||
delete conn;
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
// Command was successfully queued so exit quietly
|
|
||||||
delete mChecker;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wxMilliSleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is another copy of Audacity running. Force quit.
|
|
||||||
|
|
||||||
wxString prompt =
|
|
||||||
_("The system has detected that another copy of Audacity is running.\n") +
|
|
||||||
runningTwoCopiesStr +
|
|
||||||
_("Use the New or Open commands in the currently running Audacity\nprocess to open multiple projects simultaneously.\n");
|
|
||||||
wxMessageBox(prompt, _("Audacity is already running"),
|
|
||||||
wxOK | wxICON_ERROR);
|
|
||||||
delete mChecker;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the DDE server
|
// Get the 1st argument (filename) if there is one. Send a
|
||||||
mIPCServ = new IPCServ(appl);
|
// message even if there isn't an argument so that the existing
|
||||||
|
// Audacity will try to get the users attention.
|
||||||
|
wxString cmd;
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
cmd = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
#if defined(__WXMSW__)
|
||||||
|
// On Windows, we attempt to make a DDE connection
|
||||||
|
// to an already active Audacity. If successful, we send
|
||||||
|
// the first command line argument (the audio file name)
|
||||||
|
// to that Audacity for processing.
|
||||||
|
wxClient client;
|
||||||
|
wxConnectionBase *conn;
|
||||||
|
|
||||||
|
// We try up to 50 times since there's a small window
|
||||||
|
// where the server may not have been fully initialized.
|
||||||
|
for (int i = 0; i < 50; i++)
|
||||||
|
{
|
||||||
|
conn = client.MakeConnection(wxEmptyString, IPC_APPL, IPC_TOPIC);
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
|
bool ok = conn->Execute(cmd);
|
||||||
|
|
||||||
|
conn->Disconnect();
|
||||||
|
delete conn;
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
// Command was successfully queued so exit quietly
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wxMilliSleep(100);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// On Unix-like machines, we use a local (file based) socket to
|
||||||
|
// send the first command line argument to an already running
|
||||||
|
// Audacity.
|
||||||
|
wxUNIXaddress addr;
|
||||||
|
addr.Filename(sockFile);
|
||||||
|
|
||||||
|
// Setup the socket
|
||||||
|
wxSocketClient *sock = new wxSocketClient();
|
||||||
|
sock->SetFlags(wxSOCKET_WAITALL);
|
||||||
|
|
||||||
|
// We try up to 50 times since there's a small window
|
||||||
|
// where the server may not have been fully initialized.
|
||||||
|
for (int i = 0; i < 50; i++)
|
||||||
|
{
|
||||||
|
// Connect to the existing Audacity
|
||||||
|
sock->Connect(addr, true);
|
||||||
|
if (sock->IsConnected())
|
||||||
|
{
|
||||||
|
// Send the filename, nothing fancy, but maybe it should be?
|
||||||
|
int len = cmd.Len();
|
||||||
|
sock->Write(&len, sizeof(len));
|
||||||
|
sock->Write(cmd.c_str(), len * sizeof(wxChar));
|
||||||
|
sock->Destroy();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMilliSleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
sock->Destroy();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// There is another copy of Audacity running and we weren't able to
|
||||||
|
// communicate to it...force quit. We should never really get to this point
|
||||||
|
// but let the user know just in case.
|
||||||
|
|
||||||
|
wxString prompt =
|
||||||
|
_("The system has detected that another copy of Audacity is running.\n") +
|
||||||
|
runningTwoCopiesStr +
|
||||||
|
_("Use the New or Open commands in the currently running Audacity\nprocess to open multiple projects simultaneously.\n");
|
||||||
|
wxMessageBox(prompt, _("Audacity is already running"),
|
||||||
|
wxOK | wxICON_ERROR);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__UNIX__)
|
||||||
|
void AudacityApp::OnServerEvent(wxSocketEvent & evt)
|
||||||
|
{
|
||||||
|
wxSocketBase *sock;
|
||||||
|
|
||||||
|
// Accept all pending connection requests
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sock = mIPCServ->Accept(false);
|
||||||
|
if (sock)
|
||||||
|
{
|
||||||
|
// Setup the socket
|
||||||
|
sock->SetEventHandler(*this, ID_IPC_SOCKET);
|
||||||
|
sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
|
||||||
|
sock->Notify(true);
|
||||||
|
}
|
||||||
|
} while (sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudacityApp::OnSocketEvent(wxSocketEvent & evt)
|
||||||
|
{
|
||||||
|
wxSocketBase *sock = evt.GetSocket();
|
||||||
|
|
||||||
|
if (evt.GetSocketEvent() == wxSOCKET_LOST)
|
||||||
|
{
|
||||||
|
sock->Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have data to read so suspend further input events
|
||||||
|
sock->SetNotify(wxSOCKET_LOST);
|
||||||
|
|
||||||
|
// Read the length of the filename and bail if we have a short read
|
||||||
|
int len;
|
||||||
|
if (sock->Read(&len, sizeof(len)).LastCount() != sizeof(len))
|
||||||
|
{
|
||||||
|
sock->Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure it's in range
|
||||||
|
if (len < 0 || len >= PATH_MAX)
|
||||||
|
{
|
||||||
|
sock->Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the filename
|
||||||
|
wxString name;
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
wxChar *data = new wxChar[len];
|
||||||
|
sock->Read(data, len * sizeof(wxChar));
|
||||||
|
if (sock->LastCount() != len * sizeof(wxChar))
|
||||||
|
{
|
||||||
|
delete [] data;
|
||||||
|
sock->Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
name = wxString(data, len);
|
||||||
|
|
||||||
|
delete [] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the filename to the queue. It will be opened by
|
||||||
|
// the OnTimer() event when it is safe to do so.
|
||||||
|
ofqueue.Add(name);
|
||||||
|
|
||||||
|
sock->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void AudacityApp::PrintCommandLineHelp(void)
|
void AudacityApp::PrintCommandLineHelp(void)
|
||||||
{
|
{
|
||||||
wxPrintf(wxT("%s\n%s\n%s\n%s\n%s\n\n%s\n"),
|
wxPrintf(wxT("%s\n%s\n%s\n%s\n%s\n\n%s\n"),
|
||||||
_("Command-line options supported:"),
|
_("Command-line options supported:"),
|
||||||
/*i18n-hint: '-help' is the option and needs to stay in
|
/*i18n-hint: '-help' is the option and needs to stay in
|
||||||
* English. This displays a list of available options */
|
* English. This displays a list of available options */
|
||||||
_("\t-help (this message)"),
|
_("\t-help (this message)"),
|
||||||
/*i18n-hint '-version' needs to stay in English. */
|
/*i18n-hint '-version' needs to stay in English. */
|
||||||
_("\t-version (display Audacity version)"),
|
_("\t-version (display Audacity version)"),
|
||||||
/*i18n-hint '-test' is the option and needs to stay in
|
/*i18n-hint '-test' is the option and needs to stay in
|
||||||
* English. This runs a set of automatic tests on audacity
|
* English. This runs a set of automatic tests on audacity
|
||||||
* itself */
|
* itself */
|
||||||
_("\t-test (run self diagnostics)"),
|
_("\t-test (run self diagnostics)"),
|
||||||
/*i18n-hint '-blocksize' is the option and needs to stay in
|
/*i18n-hint '-blocksize' is the option and needs to stay in
|
||||||
* English. 'nnn' is any integer number. This controls the
|
* English. 'nnn' is any integer number. This controls the
|
||||||
* size pieces that audacity uses when writing files to the
|
* size pieces that audacity uses when writing files to the
|
||||||
* disk */
|
* disk */
|
||||||
_("\t-blocksize nnn (set max disk block size in bytes)"),
|
_("\t-blocksize nnn (set max disk block size in bytes)"),
|
||||||
_("In addition, specify the name of an audio file or Audacity project to open it."));
|
_("In addition, specify the name of an audio file or Audacity project to open it."));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1817,8 +1971,6 @@ int AudacityApp::OnExit()
|
|||||||
Dispatch();
|
Dispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete mIPCServ;
|
|
||||||
|
|
||||||
Importer::Get().Terminate();
|
Importer::Get().Terminate();
|
||||||
|
|
||||||
if(gPrefs)
|
if(gPrefs)
|
||||||
@ -1840,9 +1992,9 @@ int AudacityApp::OnExit()
|
|||||||
|
|
||||||
FinishPreferences();
|
FinishPreferences();
|
||||||
|
|
||||||
#ifdef USE_FFMPEG
|
#ifdef USE_FFMPEG
|
||||||
DropFFmpegLibs();
|
DropFFmpegLibs();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UnloadEffects();
|
UnloadEffects();
|
||||||
|
|
||||||
@ -1856,7 +2008,21 @@ int AudacityApp::OnExit()
|
|||||||
|
|
||||||
if (mLocale)
|
if (mLocale)
|
||||||
delete mLocale;
|
delete mLocale;
|
||||||
delete mChecker;
|
|
||||||
|
if (mIPCServ)
|
||||||
|
{
|
||||||
|
#if defined(__UNIX__)
|
||||||
|
wxUNIXaddress addr;
|
||||||
|
if (mIPCServ->GetLocal(addr))
|
||||||
|
{
|
||||||
|
remove(OSFILENAME(addr.Filename()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
delete mIPCServ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mChecker)
|
||||||
|
delete mChecker;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
#include <wx/snglinst.h>
|
#include <wx/snglinst.h>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
#include <wx/socket.h>
|
||||||
#include <wx/timer.h>
|
#include <wx/timer.h>
|
||||||
|
|
||||||
#include "widgets/FileHistory.h"
|
#include "widgets/FileHistory.h"
|
||||||
@ -138,6 +139,10 @@ class AudacityApp:public wxApp {
|
|||||||
|
|
||||||
void OnTimer(wxTimerEvent & event);
|
void OnTimer(wxTimerEvent & event);
|
||||||
|
|
||||||
|
// IPC communication
|
||||||
|
void OnServerEvent(wxSocketEvent & evt);
|
||||||
|
void OnSocketEvent(wxSocketEvent & evt);
|
||||||
|
|
||||||
/** \brief Mark playback as having missing aliased blockfiles
|
/** \brief Mark playback as having missing aliased blockfiles
|
||||||
*
|
*
|
||||||
* Playback will continue, but the missing files will be silenced
|
* Playback will continue, but the missing files will be silenced
|
||||||
@ -227,7 +232,11 @@ class AudacityApp:public wxApp {
|
|||||||
|
|
||||||
bool mWindowRectAlreadySaved;
|
bool mWindowRectAlreadySaved;
|
||||||
|
|
||||||
|
#if defined(__WXMSW__)
|
||||||
IPCServ *mIPCServ;
|
IPCServ *mIPCServ;
|
||||||
|
#else
|
||||||
|
wxSocketServer *mIPCServ;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user