Commit 14f0499e authored by carlosgc@webkit.org's avatar carlosgc@webkit.org
Browse files

2011-04-08 Carlos Garcia Campos <cgarcia@igalia.com>

        Reviewed by Martin Robinson.

        [GTK] Close connection when web process finishes
        https://bugs.webkit.org/show_bug.cgi?id=57540

        * Platform/CoreIPC/Connection.h:
        * Platform/CoreIPC/unix/ConnectionUnix.cpp:
        * Platform/PlatformProcessIdentifier.h: Use GPid as process
        identifier.
        * Platform/WorkQueue.h:
        * Platform/gtk/WorkQueueGtk.cpp:
        (WorkQueue::EventSource::EventSource): Add cancellable parameter.
        (WorkQueue::EventSource::cancel): New method to cancel the source.
        (WorkQueue::EventSource::performWorkOnTermination): New method to
        execute a work item called when child process has finished.
        (WorkQueue::registerEventSourceHandler): Create a GCancellable for
        the socket source.
        (WorkQueue::unregisterEventSourceHandler): Cancel the source
        instead of destroying it, this will cause the source to trigger
        with condition = 0, which makes the callback return FALSE and the
        source is destroyed.
        (WorkQueue::scheduleWorkOnSource): Pass NULL as cancellable for
        idle and timeout sources.
        (WorkQueue::scheduleWorkOnTermination): Create a child watch
        source to monitor the child process.
        * UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
        (WebKit::ProcessLauncher::launchProcess): Use GPid instead of int
        as process identifier.
        * UIProcess/WebProcessProxy.cpp:
        (WebKit::WebProcessProxy::didFinishLaunching): Call
        WorkQueue::scheduleWorkOnTermination() for GTK platform too when
        web process has been launched.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@83280 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 91206bc4
2011-04-08 Carlos Garcia Campos <cgarcia@igalia.com>
Reviewed by Martin Robinson.
[GTK] Close connection when web process finishes
https://bugs.webkit.org/show_bug.cgi?id=57540
* Platform/CoreIPC/Connection.h:
* Platform/CoreIPC/unix/ConnectionUnix.cpp:
* Platform/PlatformProcessIdentifier.h: Use GPid as process
identifier.
* Platform/WorkQueue.h:
* Platform/gtk/WorkQueueGtk.cpp:
(WorkQueue::EventSource::EventSource): Add cancellable parameter.
(WorkQueue::EventSource::cancel): New method to cancel the source.
(WorkQueue::EventSource::performWorkOnTermination): New method to
execute a work item called when child process has finished.
(WorkQueue::registerEventSourceHandler): Create a GCancellable for
the socket source.
(WorkQueue::unregisterEventSourceHandler): Cancel the source
instead of destroying it, this will cause the source to trigger
with condition = 0, which makes the callback return FALSE and the
source is destroyed.
(WorkQueue::scheduleWorkOnSource): Pass NULL as cancellable for
idle and timeout sources.
(WorkQueue::scheduleWorkOnTermination): Create a child watch
source to monitor the child process.
* UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp:
(WebKit::ProcessLauncher::launchProcess): Use GPid instead of int
as process identifier.
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didFinishLaunching): Call
WorkQueue::scheduleWorkOnTermination() for GTK platform too when
web process has been launched.
2011-04-08 Carlos Garcia Campos <cgarcia@igalia.com>
Reviewed by Martin Robinson.
......
......@@ -44,6 +44,9 @@
#include <string>
#elif PLATFORM(QT)
class QSocketNotifier;
#endif
#if PLATFORM(QT) || PLATFORM(GTK)
#include "PlatformProcessIdentifier.h"
#endif
......@@ -110,7 +113,7 @@ public:
#if PLATFORM(MAC)
void setShouldCloseConnectionOnMachExceptions();
#elif PLATFORM(QT)
#elif PLATFORM(QT) || PLATFORM(GTK)
void setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier);
#endif
......
......@@ -391,7 +391,7 @@ bool Connection::sendOutgoingMessage(MessageID messageID, PassOwnPtr<ArgumentEnc
return true;
}
#if PLATFORM(QT)
#if PLATFORM(QT) || PLATFORM(GTK)
void Connection::setShouldCloseConnectionOnProcessTermination(WebKit::PlatformProcessIdentifier process)
{
m_connectionQueue.scheduleWorkOnTermination(process, WorkItem::create(this, &Connection::connectionDidClose));
......
......@@ -40,7 +40,12 @@ typedef HANDLE PlatformProcessIdentifier;
#elif PLATFORM(QT)
typedef QProcess* PlatformProcessIdentifier;
#elif PLATFORM(GTK)
typedef pid_t PlatformProcessIdentifier;
#ifdef G_OS_WIN32
typedef void* GPid;
#else
typedef int GPid;
#endif
typedef GPid PlatformProcessIdentifier;
#endif
} // namespace WebKit
......
......@@ -46,6 +46,7 @@
class QObject;
class QThread;
#elif PLATFORM(GTK)
#include "PlatformProcessIdentifier.h"
typedef struct _GMainContext GMainContext;
typedef struct _GMainLoop GMainLoop;
#endif
......@@ -87,6 +88,7 @@ public:
#elif PLATFORM(GTK)
void registerEventSourceHandler(int, int, PassOwnPtr<WorkItem>);
void unregisterEventSourceHandler(int);
void scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier, PassOwnPtr<WorkItem>);
#endif
private:
......
......@@ -36,14 +36,20 @@
// WorkQueue::EventSource
class WorkQueue::EventSource {
public:
EventSource(GSource* dispatchSource, PassOwnPtr<WorkItem> workItem, WorkQueue* workQueue)
EventSource(GSource* dispatchSource, PassOwnPtr<WorkItem> workItem, WorkQueue* workQueue, GCancellable* cancellable)
: m_dispatchSource(dispatchSource)
, m_workItem(workItem)
, m_workQueue(workQueue)
, m_cancellable(cancellable)
{
}
GSource* dispatchSource() { return m_dispatchSource; }
void cancel()
{
if (!m_cancellable)
return;
g_cancellable_cancel(m_cancellable);
}
static gboolean executeEventSource(EventSource* eventSource)
{
......@@ -81,6 +87,12 @@ public:
return TRUE;
}
static gboolean performWorkOnTermination(GPid, gint, EventSource* eventSource)
{
executeEventSource(eventSource);
return FALSE;
}
static void deleteEventSource(EventSource* eventSource)
{
ASSERT(eventSource);
......@@ -91,6 +103,7 @@ public:
GSource* m_dispatchSource;
PassOwnPtr<WorkItem> m_workItem;
WorkQueue* m_workQueue;
GCancellable* m_cancellable;
};
// WorkQueue
......@@ -136,9 +149,10 @@ void WorkQueue::registerEventSourceHandler(int fileDescriptor, int condition, Pa
{
GRefPtr<GSocket> socket = adoptGRef(g_socket_new_from_fd(fileDescriptor, 0));
ASSERT(socket);
GSource* dispatchSource = g_socket_create_source(socket.get(), static_cast<GIOCondition>(condition), 0);
GRefPtr<GCancellable> cancellable = adoptGRef(g_cancellable_new());
GSource* dispatchSource = g_socket_create_source(socket.get(), static_cast<GIOCondition>(condition), cancellable.get());
ASSERT(dispatchSource);
EventSource* eventSource = new EventSource(dispatchSource, item, this);
EventSource* eventSource = new EventSource(dispatchSource, item, this, cancellable.get());
ASSERT(eventSource);
g_source_set_callback(dispatchSource, reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWork),
......@@ -172,7 +186,7 @@ void WorkQueue::unregisterEventSourceHandler(int fileDescriptor)
if (it != m_eventSources.end()) {
Vector<EventSource*> sources = it->second;
for (unsigned i = 0; i < sources.size(); i++)
g_source_destroy(sources[i]->dispatchSource());
sources[i]->cancel();
m_eventSources.remove(it);
}
......@@ -180,7 +194,7 @@ void WorkQueue::unregisterEventSourceHandler(int fileDescriptor)
void WorkQueue::scheduleWorkOnSource(GSource* dispatchSource, PassOwnPtr<WorkItem> item)
{
EventSource* eventSource = new EventSource(dispatchSource, item, this);
EventSource* eventSource = new EventSource(dispatchSource, item, this, 0);
g_source_set_callback(dispatchSource,
reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWorkOnce),
......@@ -206,3 +220,18 @@ void WorkQueue::scheduleWorkAfterDelay(PassOwnPtr<WorkItem> item, double delay)
scheduleWorkOnSource(dispatchSource.get(), item);
}
void WorkQueue::scheduleWorkOnTermination(WebKit::PlatformProcessIdentifier process, PassOwnPtr<WorkItem> item)
{
GRefPtr<GSource> dispatchSource = adoptGRef(g_child_watch_source_new(process));
ASSERT(dispatchSource);
EventSource* eventSource = new EventSource(dispatchSource.get(), item, this, 0);
g_source_set_callback(dispatchSource.get(),
reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWorkOnTermination),
eventSource,
reinterpret_cast<GDestroyNotify>(&WorkQueue::EventSource::deleteEventSource));
g_source_attach(dispatchSource.get(), m_eventContext);
}
......@@ -82,7 +82,7 @@ void ProcessLauncher::launchProcess()
}
close(sockets[0]);
m_processIdentifier = static_cast<pid_t>(pid);
m_processIdentifier = pid;
// We've finished launching the process, message back to the main run loop.
RunLoop::main()->scheduleWork(WorkItem::create(this, &ProcessLauncher::didFinishLaunchingProcess, m_processIdentifier, sockets[1]));
}
......
......@@ -364,7 +364,7 @@ void WebProcessProxy::didFinishLaunching(CoreIPC::Connection::Identifier connect
m_connection = CoreIPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main());
#if PLATFORM(MAC)
m_connection->setShouldCloseConnectionOnMachExceptions();
#elif PLATFORM(QT)
#elif PLATFORM(QT) || PLATFORM(GTK)
m_connection->setShouldCloseConnectionOnProcessTermination(processIdentifier());
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment