mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Fix bug 4463. The crash was due to a call to X from inside a child process.
The main change is to support/ForkedCalls.{h,cpp}. We introduce a static variable IAmAChild and a corresponding accessor. This is set to true in a new fork() method, in the branch taken by the child. (Note: fork() is safe cross-platform, as it just returns -1 if we don't have fork().) This ForkedProcess::iAmAChild() method is then used to protect GuiView::message(). As Abdel has pointed out, there may be other such calls to be protected, e.g., the emission of the Buffer::changed() signal. Those are not addressed here. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22587 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
2baffdb590
commit
1741c87a4e
@ -2260,14 +2260,12 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if !defined (HAVE_FORK)
|
||||
# define fork() -1
|
||||
#endif
|
||||
|
||||
int AutoSaveBuffer::generateChild()
|
||||
{
|
||||
// tmp_ret will be located (usually) in /tmp
|
||||
// will that be a problem?
|
||||
// Note that this calls ForkedCalls::fork(), so it's
|
||||
// ok cross-platform.
|
||||
pid_t const pid = fork();
|
||||
// If you want to debug the autosave
|
||||
// you should set pid to -1, and comment out the fork.
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "support/FileFilterList.h"
|
||||
#include "support/FileName.h"
|
||||
#include "support/filetools.h"
|
||||
#include "support/ForkedCalls.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "support/os.h"
|
||||
#include "support/Package.h"
|
||||
@ -459,6 +460,9 @@ void GuiView::dropEvent(QDropEvent* event)
|
||||
|
||||
void GuiView::message(docstring const & str)
|
||||
{
|
||||
if (ForkedProcess::iAmAChild())
|
||||
return;
|
||||
|
||||
statusBar()->showMessage(toqstr(str));
|
||||
d.statusbar_timer_.stop();
|
||||
d.statusbar_timer_.start(3000);
|
||||
|
@ -108,6 +108,9 @@ ForkedProcess::ForkedProcess()
|
||||
{}
|
||||
|
||||
|
||||
bool ForkedProcess::IAmAChild = false;
|
||||
|
||||
|
||||
void ForkedProcess::emitSignal()
|
||||
{
|
||||
if (signal_.get()) {
|
||||
@ -123,6 +126,10 @@ int ForkedProcess::run(Starttype type)
|
||||
pid_ = generateChild();
|
||||
if (pid_ <= 0) { // child or fork failed.
|
||||
retval_ = 1;
|
||||
if (pid_ == 0)
|
||||
//we also do this in fork(), too, but maybe someone will try
|
||||
//to bypass that
|
||||
IAmAChild = true;
|
||||
return retval_;
|
||||
}
|
||||
|
||||
@ -184,6 +191,18 @@ void ForkedProcess::kill(int tol)
|
||||
}
|
||||
|
||||
|
||||
pid_t ForkedProcess::fork() {
|
||||
#if !defined (HAVE_FORK)
|
||||
return -1;
|
||||
#else
|
||||
pid_t pid = ::fork();
|
||||
if (pid == 0)
|
||||
IAmAChild = true;
|
||||
return pid;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Wait for child process to finish. Returns returncode from child.
|
||||
int ForkedProcess::waitForChild()
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
///
|
||||
virtual boost::shared_ptr<ForkedProcess> clone() const = 0;
|
||||
|
||||
/** A SignalType signal is can be emitted once the forked process
|
||||
/** A SignalType signal can be emitted once the forked process
|
||||
* has finished. It passes:
|
||||
* the PID of the child and;
|
||||
* the return value from the child.
|
||||
@ -97,12 +97,21 @@ public:
|
||||
*/
|
||||
void kill(int tolerance = 5);
|
||||
|
||||
/// Returns true if this is a child process
|
||||
static bool iAmAChild() { return IAmAChild; }
|
||||
|
||||
protected:
|
||||
/** Spawn the child process.
|
||||
* Returns returncode from child.
|
||||
*/
|
||||
int run(Starttype type);
|
||||
|
||||
/// implement our own version of fork()
|
||||
/// it just returns -1 if ::fork() is not defined
|
||||
/// otherwise, it forks and sets the global child-process
|
||||
/// boolean IAmAChild
|
||||
pid_t fork();
|
||||
|
||||
/// Callback function
|
||||
SignalTypePtr signal_;
|
||||
|
||||
@ -118,6 +127,9 @@ private:
|
||||
/// generate child in background
|
||||
virtual int generateChild() = 0;
|
||||
|
||||
///
|
||||
static bool IAmAChild;
|
||||
|
||||
/// Wait for child process to finish. Updates returncode from child.
|
||||
int waitForChild();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user