[Libreoffice-commits] online.git: loolwsd/ChildProcessSession.cpp loolwsd/LOOLBroker.cpp loolwsd/LOOLWSD.cpp loolwsd/LOOLWSD.hpp loolwsd/MasterProcessSession.cpp loolwsd/MasterProcessSession.hpp
Henry Castro
hcastro at collabora.com
Wed Dec 23 09:22:40 PST 2015
loolwsd/ChildProcessSession.cpp | 10 -
loolwsd/LOOLBroker.cpp | 39 ++--
loolwsd/LOOLWSD.cpp | 375 +++++++++++++++++++++------------------
loolwsd/LOOLWSD.hpp | 3
loolwsd/MasterProcessSession.cpp | 52 +++--
loolwsd/MasterProcessSession.hpp | 7
6 files changed, 280 insertions(+), 206 deletions(-)
New commits:
commit ef9313e3a9bfc727c44c83d09653dda4bc525c5e
Author: Henry Castro <hcastro at collabora.com>
Date: Sat Dec 19 20:09:48 2015 -0500
loolwsd: deligating to loolbroker and loolkit
Change-Id: I8499540630373a1bee12a5f58fca3ed701ff6404
Reviewed-on: https://gerrit.libreoffice.org/20904
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index 95909af..b74138b 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -139,10 +139,16 @@ bool ChildProcessSession::handleInput(const char *buffer, int length)
tokens[0] == "resetselection" ||
tokens[0] == "saveas");
- if (_docType != "text" && _loKitDocument->pClass->getPart(_loKitDocument) != _clientPart)
{
- _loKitDocument->pClass->setPart(_loKitDocument, _clientPart);
+ Poco::Mutex::ScopedLock lock(_mutex);
+
+ _loKitDocument->pClass->setView(_loKitDocument, _viewId);
+ if (_docType != "text" && _loKitDocument->pClass->getPart(_loKitDocument) != _clientPart)
+ {
+ _loKitDocument->pClass->setPart(_loKitDocument, _clientPart);
+ }
}
+
if (tokens[0] == "clientzoom")
{
return clientZoom(buffer, length, tokens);
diff --git a/loolwsd/LOOLBroker.cpp b/loolwsd/LOOLBroker.cpp
index df77fa8..5a64598 100644
--- a/loolwsd/LOOLBroker.cpp
+++ b/loolwsd/LOOLBroker.cpp
@@ -701,16 +701,16 @@ int main(int argc, char** argv)
const Poco::UInt64 _childId = Util::rng::getNext();
- Path jail = Path::forDirectory(childRoot + Path::separator() + std::to_string(_childId));
- File(jail).createDirectories();
+ Path jailPath = Path::forDirectory(childRoot + Path::separator() + std::to_string(_childId));
+ File(jailPath).createDirectories();
- Path jailLOInstallation(jail, loSubPath);
+ Path jailLOInstallation(jailPath, loSubPath);
jailLOInstallation.makeDirectory();
File(jailLOInstallation).createDirectory();
// Copy (link) LO installation and other necessary files into it from the template
- linkOrCopy(sysTemplate, jail);
+ linkOrCopy(sysTemplate, jailPath);
linkOrCopy(loTemplate, jailLOInstallation);
// It is necessary to deploy loolkit process to chroot jail.
@@ -719,34 +719,45 @@ int main(int argc, char** argv)
std::cout << Util::logPrefix() << "loolkit does not exists" << std::endl;
exit(-1);
}
- File("loolkit").copyTo(Path(jail, "/usr/bin").toString());
+ File("loolkit").copyTo(Path(jailPath, "/usr/bin").toString());
+
+ // We need this because sometimes the hostname is not resolved
+ std::vector<std::string> networkFiles = {"/etc/host.conf", "/etc/hosts", "/etc/nsswitch.conf", "/etc/resolv.conf"};
+ for (std::vector<std::string>::iterator it = networkFiles.begin(); it != networkFiles.end(); ++it)
+ {
+ File networkFile(*it);
+ if (networkFile.exists())
+ {
+ networkFile.copyTo(Path(jailPath, "/etc").toString());
+ }
+ }
#ifdef __linux
// Create the urandom and random devices
- File(Path(jail, "/dev")).createDirectory();
- if (mknod((jail.toString() + "/dev/random").c_str(),
+ File(Path(jailPath, "/dev")).createDirectory();
+ if (mknod((jailPath.toString() + "/dev/random").c_str(),
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
makedev(1, 8)) != 0)
{
std::cout << Util::logPrefix() +
- "mknod(" + jail.toString() + "/dev/random) failed: " +
+ "mknod(" + jailPath.toString() + "/dev/random) failed: " +
strerror(errno) << std::endl;
}
- if (mknod((jail.toString() + "/dev/urandom").c_str(),
+ if (mknod((jailPath.toString() + "/dev/urandom").c_str(),
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
makedev(1, 9)) != 0)
{
std::cout << Util::logPrefix() +
- "mknod(" + jail.toString() + "/dev/urandom) failed: " +
+ "mknod(" + jailPath.toString() + "/dev/urandom) failed: " +
strerror(errno) << std::endl;
}
#endif
- std::cout << Util::logPrefix() << "loolbroker -> chroot(\"" + jail.toString() + "\")" << std::endl;
- if (chroot(jail.toString().c_str()) == -1)
+ std::cout << Util::logPrefix() << "loolbroker -> chroot(\"" + jailPath.toString() + "\")" << std::endl;
+ if (chroot(jailPath.toString().c_str()) == -1)
{
- std::cout << Util::logPrefix() << "chroot(\"" + jail.toString() + "\") failed: " + strerror(errno) << std::endl;
+ std::cout << Util::logPrefix() << "chroot(\"" + jailPath.toString() + "\") failed: " + strerror(errno) << std::endl;
exit(-1);
}
@@ -758,6 +769,8 @@ int main(int argc, char** argv)
#ifdef __linux
dropCapability(CAP_SYS_CHROOT);
+ dropCapability(CAP_MKNOD);
+ dropCapability(CAP_FOWNER);
#else
dropCapability();
#endif
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 229f78d..41da9bb 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -148,8 +148,172 @@ using Poco::Net::Socket;
using Poco::ThreadLocal;
using Poco::Random;
using Poco::NamedMutex;
+using Poco::ProcessHandle;
using Poco::URI;
+namespace
+{
+ ThreadLocal<std::string> sourceForLinkOrCopy;
+ ThreadLocal<Path> destinationForLinkOrCopy;
+
+ int linkOrCopyFunction(const char *fpath,
+ const struct stat* /*sb*/,
+ int typeflag,
+ struct FTW* /*ftwbuf*/)
+ {
+ if (strcmp(fpath, sourceForLinkOrCopy->c_str()) == 0)
+ return 0;
+
+ assert(fpath[strlen(sourceForLinkOrCopy->c_str())] == '/');
+ const char *relativeOldPath = fpath + strlen(sourceForLinkOrCopy->c_str()) + 1;
+
+#ifdef __APPLE__
+ if (strcmp(relativeOldPath, "PkgInfo") == 0)
+ return 0;
+#endif
+
+ Path newPath(*destinationForLinkOrCopy, Path(relativeOldPath));
+
+ switch (typeflag)
+ {
+ case FTW_F:
+ File(newPath.parent()).createDirectories();
+ if (link(fpath, newPath.toString().c_str()) == -1)
+ {
+ Application::instance().logger().error(Util::logPrefix() +
+ "link(\"" + fpath + "\",\"" + newPath.toString() + "\") failed: " +
+ strerror(errno));
+ exit(1);
+ }
+ break;
+ case FTW_DP:
+ {
+ struct stat st;
+ if (stat(fpath, &st) == -1)
+ {
+ Application::instance().logger().error(Util::logPrefix() +
+ "stat(\"" + fpath + "\") failed: " +
+ strerror(errno));
+ return 1;
+ }
+ File(newPath).createDirectories();
+ struct utimbuf ut;
+ ut.actime = st.st_atime;
+ ut.modtime = st.st_mtime;
+ if (utime(newPath.toString().c_str(), &ut) == -1)
+ {
+ Application::instance().logger().error(Util::logPrefix() +
+ "utime(\"" + newPath.toString() + "\", &ut) failed: " +
+ strerror(errno));
+ return 1;
+ }
+ }
+ break;
+ case FTW_DNR:
+ Application::instance().logger().error(Util::logPrefix() +
+ "Cannot read directory '" + fpath + "'");
+ return 1;
+ case FTW_NS:
+ Application::instance().logger().error(Util::logPrefix() +
+ "nftw: stat failed for '" + fpath + "'");
+ return 1;
+ case FTW_SLN:
+ Application::instance().logger().information(Util::logPrefix() +
+ "nftw: symlink to nonexistent file: '" + fpath + "', ignored");
+ break;
+ default:
+ assert(false);
+ }
+ return 0;
+ }
+
+ void linkOrCopy(const std::string& source, const Path& destination)
+ {
+ *sourceForLinkOrCopy = source;
+ if (sourceForLinkOrCopy->back() == '/')
+ sourceForLinkOrCopy->pop_back();
+ *destinationForLinkOrCopy = destination;
+ if (nftw(source.c_str(), linkOrCopyFunction, 10, FTW_DEPTH) == -1)
+ Application::instance().logger().error(Util::logPrefix() +
+ "linkOrCopy: nftw() failed for '" + source + "'");
+ }
+
+ void dropCapability(
+#ifdef __linux
+ cap_value_t capability
+#endif
+ )
+ {
+#ifdef __linux
+ cap_t caps;
+ cap_value_t cap_list[] = { capability };
+
+ caps = cap_get_proc();
+ if (caps == NULL)
+ {
+ Application::instance().logger().error(Util::logPrefix() + "cap_get_proc() failed: " + strerror(errno));
+ exit(1);
+ }
+
+ if (cap_set_flag(caps, CAP_EFFECTIVE, sizeof(cap_list)/sizeof(cap_list[0]), cap_list, CAP_CLEAR) == -1 ||
+ cap_set_flag(caps, CAP_PERMITTED, sizeof(cap_list)/sizeof(cap_list[0]), cap_list, CAP_CLEAR) == -1)
+ {
+ Application::instance().logger().error(Util::logPrefix() + "cap_set_flag() failed: " + strerror(errno));
+ exit(1);
+ }
+
+ if (cap_set_proc(caps) == -1)
+ {
+ Application::instance().logger().error(std::string("cap_set_proc() failed: ") + strerror(errno));
+ exit(1);
+ }
+
+ char *capText = cap_to_text(caps, NULL);
+ Application::instance().logger().information(Util::logPrefix() + "Capabilities now: " + capText);
+ cap_free(capText);
+
+ cap_free(caps);
+#endif
+ // We assume that on non-Linux we don't need to be root to be able to hardlink to files we
+ // don't own, so drop root.
+ if (geteuid() == 0 && getuid() != 0)
+ {
+ // The program is setuid root. Not normal on Linux where we use setcap, but if this
+ // needs to run on non-Linux Unixes, setuid root is what it will bneed to be to be able
+ // to do chroot().
+ if (setuid(getuid()) != 0)
+ {
+ Application::instance().logger().error(std::string("setuid() failed: ") + strerror(errno));
+ }
+ }
+#if ENABLE_DEBUG
+ if (geteuid() == 0 && getuid() == 0)
+ {
+#ifdef __linux
+ // Argh, awful hack
+ if (capability == CAP_FOWNER)
+ return;
+#endif
+
+ // Running under sudo, probably because being debugged? Let's drop super-user rights.
+ LOOLWSD::runningAsRoot = true;
+ if (LOOLWSD::uid == 0)
+ {
+ struct passwd *nobody = getpwnam("nobody");
+ if (nobody)
+ LOOLWSD::uid = nobody->pw_uid;
+ else
+ LOOLWSD::uid = 65534;
+ }
+ if (setuid(LOOLWSD::uid) != 0)
+ {
+ Application::instance().logger().error(std::string("setuid() failed: ") + strerror(errno));
+ }
+ }
+#endif
+ }
+}
+
class QueueHandler: public Runnable
{
public:
@@ -391,7 +555,7 @@ public:
do
{
- char buffer[200000];
+ char buffer[200000]; //FIXME: Dynamic?
if ((pollTimeout = ws->poll(waitTime, Socket::SELECT_READ)))
{
@@ -752,169 +916,6 @@ void LOOLWSD::displayHelp()
helpFormatter.format(std::cout);
}
-namespace
-{
- ThreadLocal<std::string> sourceForLinkOrCopy;
- ThreadLocal<Path> destinationForLinkOrCopy;
-
- int linkOrCopyFunction(const char *fpath,
- const struct stat* /*sb*/,
- int typeflag,
- struct FTW* /*ftwbuf*/)
- {
- if (strcmp(fpath, sourceForLinkOrCopy->c_str()) == 0)
- return 0;
-
- assert(fpath[strlen(sourceForLinkOrCopy->c_str())] == '/');
- const char *relativeOldPath = fpath + strlen(sourceForLinkOrCopy->c_str()) + 1;
-
-#ifdef __APPLE__
- if (strcmp(relativeOldPath, "PkgInfo") == 0)
- return 0;
-#endif
-
- Path newPath(*destinationForLinkOrCopy, Path(relativeOldPath));
-
- switch (typeflag)
- {
- case FTW_F:
- File(newPath.parent()).createDirectories();
- if (link(fpath, newPath.toString().c_str()) == -1)
- {
- Application::instance().logger().error(Util::logPrefix() +
- "link(\"" + fpath + "\",\"" + newPath.toString() + "\") failed: " +
- strerror(errno));
- exit(1);
- }
- break;
- case FTW_DP:
- {
- struct stat st;
- if (stat(fpath, &st) == -1)
- {
- Application::instance().logger().error(Util::logPrefix() +
- "stat(\"" + fpath + "\") failed: " +
- strerror(errno));
- return 1;
- }
- File(newPath).createDirectories();
- struct utimbuf ut;
- ut.actime = st.st_atime;
- ut.modtime = st.st_mtime;
- if (utime(newPath.toString().c_str(), &ut) == -1)
- {
- Application::instance().logger().error(Util::logPrefix() +
- "utime(\"" + newPath.toString() + "\", &ut) failed: " +
- strerror(errno));
- return 1;
- }
- }
- break;
- case FTW_DNR:
- Application::instance().logger().error(Util::logPrefix() +
- "Cannot read directory '" + fpath + "'");
- return 1;
- case FTW_NS:
- Application::instance().logger().error(Util::logPrefix() +
- "nftw: stat failed for '" + fpath + "'");
- return 1;
- case FTW_SLN:
- Application::instance().logger().information(Util::logPrefix() +
- "nftw: symlink to nonexistent file: '" + fpath + "', ignored");
- break;
- default:
- assert(false);
- }
- return 0;
- }
-
- void linkOrCopy(const std::string& source, const Path& destination)
- {
- *sourceForLinkOrCopy = source;
- if (sourceForLinkOrCopy->back() == '/')
- sourceForLinkOrCopy->pop_back();
- *destinationForLinkOrCopy = destination;
- if (nftw(source.c_str(), linkOrCopyFunction, 10, FTW_DEPTH) == -1)
- Application::instance().logger().error(Util::logPrefix() +
- "linkOrCopy: nftw() failed for '" + source + "'");
- }
-
- void dropCapability(
-#ifdef __linux
- cap_value_t capability
-#endif
- )
- {
-#ifdef __linux
- cap_t caps;
- cap_value_t cap_list[] = { capability };
-
- caps = cap_get_proc();
- if (caps == NULL)
- {
- Application::instance().logger().error(Util::logPrefix() + "cap_get_proc() failed: " + strerror(errno));
- exit(1);
- }
-
- if (cap_set_flag(caps, CAP_EFFECTIVE, sizeof(cap_list)/sizeof(cap_list[0]), cap_list, CAP_CLEAR) == -1 ||
- cap_set_flag(caps, CAP_PERMITTED, sizeof(cap_list)/sizeof(cap_list[0]), cap_list, CAP_CLEAR) == -1)
- {
- Application::instance().logger().error(Util::logPrefix() + "cap_set_flag() failed: " + strerror(errno));
- exit(1);
- }
-
- if (cap_set_proc(caps) == -1)
- {
- Application::instance().logger().error(std::string("cap_set_proc() failed: ") + strerror(errno));
- exit(1);
- }
-
- char *capText = cap_to_text(caps, NULL);
- Application::instance().logger().information(Util::logPrefix() + "Capabilities now: " + capText);
- cap_free(capText);
-
- cap_free(caps);
-#endif
- // We assume that on non-Linux we don't need to be root to be able to hardlink to files we
- // don't own, so drop root.
- if (geteuid() == 0 && getuid() != 0)
- {
- // The program is setuid root. Not normal on Linux where we use setcap, but if this
- // needs to run on non-Linux Unixes, setuid root is what it will bneed to be to be able
- // to do chroot().
- if (setuid(getuid()) != 0)
- {
- Application::instance().logger().error(std::string("setuid() failed: ") + strerror(errno));
- }
- }
-#if ENABLE_DEBUG
- if (geteuid() == 0 && getuid() == 0)
- {
-#ifdef __linux
- // Argh, awful hack
- if (capability == CAP_FOWNER)
- return;
-#endif
-
- // Running under sudo, probably because being debugged? Let's drop super-user rights.
- LOOLWSD::runningAsRoot = true;
- if (LOOLWSD::uid == 0)
- {
- struct passwd *nobody = getpwnam("nobody");
- if (nobody)
- LOOLWSD::uid = nobody->pw_uid;
- else
- LOOLWSD::uid = 65534;
- }
- if (setuid(LOOLWSD::uid) != 0)
- {
- Application::instance().logger().error(std::string("setuid() failed: ") + strerror(errno));
- }
- }
-#endif
- }
-}
-
// Writer, Impress or Calc
void LOOLWSD::componentMain()
{
@@ -1208,11 +1209,34 @@ int LOOLWSD::createDesktop()
return Application::EXIT_OK;
}
-void LOOLWSD::startupDesktop(int nDesktops)
+int LOOLWSD::createBroker()
{
- for (int nCntr = nDesktops; nCntr; nCntr--)
+ Process::Args args;
+
+ args.push_back("--losubpath=" + LOOLWSD::loSubPath);
+ args.push_back("--systemplate=" + sysTemplate);
+ args.push_back("--lotemplate=" + loTemplate);
+ args.push_back("--childroot=" + childRoot);
+ args.push_back("--numprespawns=" + std::to_string(_numPreSpawnedChildren));
+
+ std::string executable = Path(Application::instance().commandPath()).parent().toString() + "loolbroker";
+
+ const auto msg = Util::logPrefix() + "Launching broker: " + executable + " "
+ + Poco::cat(std::string(" "), args.begin(), args.end());
+ Application::instance().logger().information(msg);
+
+ ProcessHandle child = Process::launch(executable, args);
+
+ MasterProcessSession::_childProcesses[child.id()] = child.id();
+
+ return Application::EXIT_OK;
+}
+
+void LOOLWSD::startupBroker(const signed nBrokers)
+{
+ for (signed nCntr = nBrokers; nCntr > 0; --nCntr)
{
- if (createDesktop() < 0)
+ if (createBroker() < 0)
break;
}
}
@@ -1274,7 +1298,7 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
_namedMutexLOOL.lock();
- startupDesktop(1);
+ startupBroker(1);
#ifdef __linux
dropCapability(CAP_SYS_CHROOT);
@@ -1299,6 +1323,12 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
srv2.start();
+ if ( (writerBroker = open(FIFO_FILE.c_str(), O_WRONLY) ) < 0 )
+ {
+ std::cout << Util::logPrefix() << "Pipe opened for writing" << strerror(errno) << std::endl;
+ return Application::EXIT_UNAVAILABLE;
+ }
+
_namedMutexLOOL.unlock();
TestInput input(*this, svs, srv);
@@ -1361,9 +1391,12 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
threadPool.joinAll();
threadPool2.joinAll();
- // Clear sessions to pre-spawned child processes that have connected
- // but are not yet assigned a document to work on.
- MasterProcessSession::_availableChildSessions.clear();
+ // Terminate child processes
+ for (auto i : MasterProcessSession::_childProcesses)
+ {
+ logger().information(Util::logPrefix() + "Requesting child process " + std::to_string(i.first) + " to terminate");
+ Process::requestTermination(i.first);
+ }
// wait broker process finish
waitpid(-1, &status, WUNTRACED);
diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp
index 637c246..3f7cfee 100644
--- a/loolwsd/LOOLWSD.hpp
+++ b/loolwsd/LOOLWSD.hpp
@@ -75,6 +75,9 @@ private:
int createComponent();
int createDesktop();
+ void startupBroker(int nBroker);
+ int createBroker();
+
#if ENABLE_DEBUG
public:
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index fb4af0b..513e200 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -46,7 +46,7 @@ using Poco::Util::Application;
std::map<Process::PID, UInt64> MasterProcessSession::_childProcesses;
-std::set<std::shared_ptr<MasterProcessSession>> MasterProcessSession::_availableChildSessions;
+std::map<Thread::TID, std::shared_ptr<MasterProcessSession>> MasterProcessSession::_availableChildSessions;
std::mutex MasterProcessSession::_availableChildSessionMutex;
std::condition_variable MasterProcessSession::_availableChildSessionCV;
@@ -202,17 +202,19 @@ bool MasterProcessSession::handleInput(const char *buffer, int length)
sendTextFrame("error: cmd=child kind=invalid");
return false;
}
- if (tokens.count() != 3)
+ if (tokens.count() != 4)
{
sendTextFrame("error: cmd=child kind=syntax");
return false;
}
UInt64 childId = std::stoull(tokens[1]);
- Process::PID pidChild = std::stoull(tokens[2]);
+ Thread::TID tId = std::stoull(tokens[2]);
+ Process::PID pidChild = std::stoull(tokens[3]);
std::unique_lock<std::mutex> lock(_availableChildSessionMutex);
- _availableChildSessions.insert(shared_from_this());
+ _availableChildSessions.insert(std::pair<Thread::TID, std::shared_ptr<MasterProcessSession>> (tId, shared_from_this()));
+ std::cout << Util::logPrefix() << _kindString << ",Inserted " << this << " id=" << childId << " into _availableChildSessions, size=" << _availableChildSessions.size() << std::endl;
std::cout << Util::logPrefix() << "Inserted " << this << " id=" << childId << " into _availableChildSessions, size=" << _availableChildSessions.size() << std::endl;
_childId = childId;
_pidChild = pidChild;
@@ -543,30 +545,48 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni
void MasterProcessSession::dispatchChild()
{
+ short nRequest = 3;
+ bool bFound = false;
+
// Copy document into jail using the fixed name
std::shared_ptr<MasterProcessSession> childSession;
std::unique_lock<std::mutex> lock(_availableChildSessionMutex);
- std::cout << Util::logPrefix() << "_availableChildSessions size=" << _availableChildSessions.size() << std::endl;
+ std::cout << Util::logPrefix() << "waiting for a child session permission for " << Thread::currentTid() << std::endl;
+ while (nRequest-- && !bFound)
+ {
+ _availableChildSessionCV.wait_for(
+ lock,
+ std::chrono::milliseconds(2000),
+ [&bFound]
+ {
+ return (bFound = _availableChildSessions.find(Thread::currentTid()) != _availableChildSessions.end());
+ });
+
+ if (!bFound)
+ {
+ std::cout << Util::logPrefix() << "trying ..." << nRequest << std::endl;
+ // request again new URL session
+ std::string aMessage = "request " + std::to_string(Thread::currentTid()) + " " + _docURL + "\r\n";
+ Util::writeFIFO(LOOLWSD::writerBroker, aMessage.c_str(), aMessage.length());
+ }
+ }
- if (_availableChildSessions.size() == 0)
+ if ( bFound )
{
- std::cout << Util::logPrefix() << "waiting for a child session to become available" << std::endl;
- _availableChildSessionCV.wait(lock, [] { return _availableChildSessions.size() > 0; });
- std::cout << Util::logPrefix() << "waiting done" << std::endl;
+ std::cout << Util::logPrefix() << "waiting child session permission, done!" << std::endl;
+ childSession = _availableChildSessions[Thread::currentTid()];
+ _availableChildSessions.erase(Thread::currentTid());
}
- childSession = *(_availableChildSessions.begin());
- _availableChildSessions.erase(childSession);
lock.unlock();
- if (_availableChildSessions.size() == 0 && !LOOLWSD::doTest)
+ if ( !nRequest && !bFound )
{
- LOOLWSD::_namedMutexLOOL.lock();
- std::cout << Util::logPrefix() << "No available child sessions, queue new child session" << std::endl;
- LOOLWSD::_sharedForkChild.begin()[0] = LOOLWSD::_numPreSpawnedChildren;
- LOOLWSD::_namedMutexLOOL.unlock();
+ // it cannot get connected. shutdown.
+ Util::shutdownWebSocket(*_ws);
+ return;
}
// Assume a valid URI
diff --git a/loolwsd/MasterProcessSession.hpp b/loolwsd/MasterProcessSession.hpp
index ec5ff0d..4b9329a 100644
--- a/loolwsd/MasterProcessSession.hpp
+++ b/loolwsd/MasterProcessSession.hpp
@@ -42,10 +42,6 @@ public:
*/
std::string getSaveAs();
- // Sessions to pre-spawned child processes that have connected but are not yet assigned a
- // document to work on.
- static std::set<std::shared_ptr<MasterProcessSession>> _availableChildSessions;
-
protected:
bool invalidateTiles(const char *buffer, int length, Poco::StringTokenizer& tokens);
@@ -67,6 +63,9 @@ public:
// per document being edited (i.e., per child process).
std::weak_ptr<MasterProcessSession> _peer;
+ // Sessions to pre-spawned child processes that have connected but are not yet assigned a
+ // document to work on.
+ static std::map<Poco::Thread::TID, std::shared_ptr<MasterProcessSession>> _availableChildSessions;
static std::mutex _availableChildSessionMutex;
static std::condition_variable _availableChildSessionCV;
More information about the Libreoffice-commits
mailing list