Do not reply sync messages when window is closed.

This commit is contained in:
Cheng Zhao 2013-09-22 10:43:54 +08:00
parent 1e4762ce92
commit 761b9d22c8
4 changed files with 27 additions and 11 deletions

View file

@ -4,9 +4,9 @@
#include "browser/api/atom_api_event.h" #include "browser/api/atom_api_event.h"
#include "browser/native_window.h"
#include "common/api/api_messages.h" #include "common/api/api_messages.h"
#include "common/string16_conversions.h" #include "common/string16_conversions.h"
#include "ipc/ipc_sender.h"
using node::node_isolate; using node::node_isolate;
@ -23,6 +23,8 @@ Event::Event()
} }
Event::~Event() { Event::~Event() {
if (sender_)
sender_->RemoveObserver(this);
} }
// static // static
@ -46,11 +48,18 @@ v8::Handle<v8::Object> Event::CreateV8Object() {
return scope.Close(v8_event); return scope.Close(v8_event);
} }
void Event::SetSenderAndMessage(IPC::Sender* sender, IPC::Message* message) { void Event::SetSenderAndMessage(NativeWindow* sender, IPC::Message* message) {
DCHECK(!sender_); DCHECK(!sender_);
DCHECK(!message_); DCHECK(!message_);
sender_ = sender; sender_ = sender;
message_ = message; message_ = message;
sender_->AddObserver(this);
}
void Event::OnWindowClosed() {
sender_ = NULL;
message_ = NULL;
} }
// static // static
@ -78,7 +87,7 @@ v8::Handle<v8::Value> Event::SendReply(const v8::Arguments& args) {
if (event == NULL) if (event == NULL)
return node::ThrowError("Event is already destroyed"); return node::ThrowError("Event is already destroyed");
if (event->sender_ == NULL) if (event->message_ == NULL)
return node::ThrowError("Can only send reply to synchronous events once"); return node::ThrowError("Can only send reply to synchronous events once");
string16 json = V8ValueToUTF16(args[0]); string16 json = V8ValueToUTF16(args[0]);
@ -86,7 +95,6 @@ v8::Handle<v8::Value> Event::SendReply(const v8::Arguments& args) {
AtomViewHostMsg_Message_Sync::WriteReplyParams(event->message_, json); AtomViewHostMsg_Message_Sync::WriteReplyParams(event->message_, json);
event->sender_->Send(event->message_); event->sender_->Send(event->message_);
event->sender_ = NULL;
event->message_ = NULL; event->message_ = NULL;
return v8::Undefined(); return v8::Undefined();
} }

View file

@ -6,19 +6,23 @@
#define ATOM_BROWSER_ATOM_API_EVENT_H_ #define ATOM_BROWSER_ATOM_API_EVENT_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/string16.h" #include "base/string16.h"
#include "browser/native_window_observer.h"
#include "vendor/node/src/node_object_wrap.h" #include "vendor/node/src/node_object_wrap.h"
namespace IPC { namespace IPC {
class Message; class Message;
class Sender;
} }
namespace atom { namespace atom {
class NativeWindow;
namespace api { namespace api {
class Event : public node::ObjectWrap { class Event : public node::ObjectWrap,
public NativeWindowObserver {
public: public:
virtual ~Event(); virtual ~Event();
@ -26,7 +30,7 @@ class Event : public node::ObjectWrap {
static v8::Handle<v8::Object> CreateV8Object(); static v8::Handle<v8::Object> CreateV8Object();
// Pass the sender and message to be replied. // Pass the sender and message to be replied.
void SetSenderAndMessage(IPC::Sender* sender, IPC::Message* message); void SetSenderAndMessage(NativeWindow* sender, IPC::Message* message);
// Accessor to return handle_, this follows Google C++ Style. // Accessor to return handle_, this follows Google C++ Style.
v8::Persistent<v8::Object>& handle() { return handle_; } v8::Persistent<v8::Object>& handle() { return handle_; }
@ -37,6 +41,9 @@ class Event : public node::ObjectWrap {
protected: protected:
Event(); Event();
// NativeWindowObserver implementations:
virtual void OnWindowClosed() OVERRIDE;
private: private:
static v8::Handle<v8::Value> New(const v8::Arguments& args); static v8::Handle<v8::Value> New(const v8::Arguments& args);
@ -46,7 +53,7 @@ class Event : public node::ObjectWrap {
static v8::Persistent<v8::FunctionTemplate> constructor_template_; static v8::Persistent<v8::FunctionTemplate> constructor_template_;
// Replyer for the synchronous messages. // Replyer for the synchronous messages.
IPC::Sender* sender_; NativeWindow* sender_;
IPC::Message* message_; IPC::Message* message_;
bool prevent_default_; bool prevent_default_;

View file

@ -76,7 +76,7 @@ void AtomBrowserBindings::OnRendererMessageSync(
int routing_id, int routing_id,
const string16& channel, const string16& channel,
const base::ListValue& args, const base::ListValue& args,
IPC::Sender* sender, NativeWindow* sender,
IPC::Message* message) { IPC::Message* message) {
v8::HandleScope scope; v8::HandleScope scope;

View file

@ -14,11 +14,12 @@ class ListValue;
namespace IPC { namespace IPC {
class Message; class Message;
class Sender;
} }
namespace atom { namespace atom {
class NativeWindow;
class AtomBrowserBindings : public AtomBindings { class AtomBrowserBindings : public AtomBindings {
public: public:
AtomBrowserBindings(); AtomBrowserBindings();
@ -38,7 +39,7 @@ class AtomBrowserBindings : public AtomBindings {
int routing_id, int routing_id,
const string16& channel, const string16& channel,
const base::ListValue& args, const base::ListValue& args,
IPC::Sender* sender, NativeWindow* sender,
IPC::Message* message); IPC::Message* message);
// The require('atom').browserMainParts object. // The require('atom').browserMainParts object.