remote_object_freer.cc 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright (c) 2016 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/common/api/remote_object_freer.h"
  5. #include "atom/common/api/api_messages.h"
  6. #include "base/strings/utf_string_conversions.h"
  7. #include "base/values.h"
  8. #include "content/public/renderer/render_frame.h"
  9. #include "third_party/blink/public/web/web_local_frame.h"
  10. using blink::WebLocalFrame;
  11. namespace atom {
  12. namespace {
  13. content::RenderFrame* GetCurrentRenderFrame() {
  14. WebLocalFrame* frame = WebLocalFrame::FrameForCurrentContext();
  15. if (!frame)
  16. return nullptr;
  17. return content::RenderFrame::FromWebFrame(frame);
  18. }
  19. } // namespace
  20. // static
  21. void RemoteObjectFreer::BindTo(v8::Isolate* isolate,
  22. v8::Local<v8::Object> target,
  23. const std::string& context_id,
  24. int object_id) {
  25. new RemoteObjectFreer(isolate, target, context_id, object_id);
  26. }
  27. // static
  28. void RemoteObjectFreer::AddRef(const std::string& context_id, int object_id) {
  29. ref_mapper_[context_id][object_id]++;
  30. }
  31. // static
  32. std::map<std::string, std::map<int, int>> RemoteObjectFreer::ref_mapper_;
  33. RemoteObjectFreer::RemoteObjectFreer(v8::Isolate* isolate,
  34. v8::Local<v8::Object> target,
  35. const std::string& context_id,
  36. int object_id)
  37. : ObjectLifeMonitor(isolate, target),
  38. context_id_(context_id),
  39. object_id_(object_id),
  40. routing_id_(MSG_ROUTING_NONE) {
  41. content::RenderFrame* render_frame = GetCurrentRenderFrame();
  42. if (render_frame) {
  43. routing_id_ = render_frame->GetRoutingID();
  44. }
  45. }
  46. RemoteObjectFreer::~RemoteObjectFreer() {}
  47. void RemoteObjectFreer::RunDestructor() {
  48. content::RenderFrame* render_frame =
  49. content::RenderFrame::FromRoutingID(routing_id_);
  50. if (!render_frame)
  51. return;
  52. auto* channel = "ipc-internal-message";
  53. base::ListValue args;
  54. args.AppendString("ELECTRON_BROWSER_DEREFERENCE");
  55. args.AppendString(context_id_);
  56. args.AppendInteger(object_id_);
  57. args.AppendInteger(ref_mapper_[context_id_][object_id_]);
  58. // Reset our local ref count in case we are in a GC race condition and will
  59. // get more references in an inbound IPC message
  60. ref_mapper_[context_id_].erase(object_id_);
  61. if (ref_mapper_[context_id_].empty())
  62. ref_mapper_.erase(context_id_);
  63. render_frame->Send(new AtomFrameHostMsg_Message(render_frame->GetRoutingID(),
  64. channel, args));
  65. }
  66. } // namespace atom