Files
MapLibreParticleLab/src/node_request.hpp
Thiago Marcos P. Santos 34ef7ac003 Implement request coalescing and synchronous request cancellation
When requests are made to the FileSource, we now group them by
resource, similarly to what is done on the native implementation. The
file source will reuse the same Response for all the requests on the
observer list.

The NodeRequest no longer holds a reference to the mbgl::Request, so
we can cancel it synchronously. This is needed to avoid a deadlock
when releasing the NodeMap resources with pending requests.

Before:

- Main thread | NodeMap::release()
- Main thread | mbgl::~Map()
- Main thread | Blocks waiting for the Map thread to join
- Map thread  | mbgl::Request::cancel()
- Map thread  | NodeFileSource posts the "cancel" message to main thread
- *deadlock*  | Map thread cannot join because mbgl::Request holds a
                reference to the Map thread main loop. Main thread is
                blocked, never gets the "cancel" message.

Now:

- Main thread | NodeMap::release()
- Main thread | mbgl::~Map()
- Main thread | Blocks waiting for the Map thread to join
- Map thread  | Request::cancel()
- Map thread  | NodeFileSource::cancel(), destroys the mbgl::Request
                synchronously, mutex guarded access. We also send
                a notification to cancel the NodeRequest on the main
                thread.
- Map thread  | Map thread joins.
- Main thread | NodeMap::release() returns
- Main thread | NodeRequest gets canceled. If NodeRequest replies
                before it gets the "cancel" message, nothing happens,
                notification gets discarded.
2015-06-15 01:52:15 +03:00

44 lines
1.1 KiB
C++

#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wshadow"
#include <node.h>
#include <nan.h>
#pragma GCC diagnostic pop
#include <mbgl/storage/resource.hpp>
#include <memory>
class NodeFileSource;
namespace node_mbgl {
class NodeRequest : public node::ObjectWrap {
////////////////////////////////////////////////////////////////////////////////////////////////
// Static Node Methods
public:
static void Init(v8::Handle<v8::Object> target);
static NAN_METHOD(New);
static NAN_METHOD(Respond);
static v8::Handle<v8::Object> Create(v8::Handle<v8::Object> source, const mbgl::Resource& resource);
static v8::Persistent<v8::FunctionTemplate> constructorTemplate;
////////////////////////////////////////////////////////////////////////////////////////////////
// Instance
public:
NodeRequest(v8::Local<v8::Object> source, const mbgl::Resource& resource);
~NodeRequest();
void cancel();
private:
v8::Persistent<v8::Object> source;
std::unique_ptr<mbgl::Resource> resource;
};
}