allow providing a callback to uv_messenger_stop to prevent mismatched new/free

This commit is contained in:
Konstantin Käfer
2014-10-30 17:46:57 -04:00
parent 1955600904
commit 80366bc615
4 changed files with 17 additions and 7 deletions

View File

@@ -15,13 +15,14 @@ struct uv_messenger_s {
uv_mutex_t mutex;
uv_async_t async;
uv_messenger_cb callback;
uv_messenger_stop_cb stop_callback;
void *data;
void *queue[2];
};
int uv_messenger_init(uv_loop_t *loop, uv_messenger_t *msgr, uv_messenger_cb callback);
void uv_messenger_send(uv_messenger_t *msgr, void *arg);
void uv_messenger_stop(uv_messenger_t *msgr);
void uv_messenger_stop(uv_messenger_t *msgr, uv_messenger_stop_cb stop_callback);
void uv_messenger_ref(uv_messenger_t *msgr);
void uv_messenger_unref(uv_messenger_t *msgr);

View File

@@ -23,9 +23,9 @@ FileSource::FileSource(uv_loop_t *loop_, const std::string &path)
FileSource::~FileSource() {
assert(thread_id == uv_thread_self());
uv_messenger_stop(queue);
// NOTE: We don't need to delete the messenger since it will be deleted by the
// uv_messenger_stop() function.
uv_messenger_stop(queue, [](uv_messenger_t *msgr) {
delete msgr;
});
util::ptr<BaseRequest> req;

View File

@@ -2,6 +2,7 @@
#include <mbgl/util/queue.h>
#include <stdlib.h>
#include <assert.h>
typedef struct {
void *data;
@@ -46,6 +47,7 @@ int uv_messenger_init(uv_loop_t *loop, uv_messenger_t *msgr, uv_messenger_cb cal
}
msgr->callback = callback;
msgr->stop_callback = NULL;
QUEUE_INIT(&msgr->queue);
@@ -73,9 +75,12 @@ void uv_messenger_unref(uv_messenger_t *msgr) {
}
void uv__messenger_stop_callback(uv_handle_t *handle) {
free((uv_messenger_t *)handle->data);
uv_messenger_t *msgr = (uv_messenger_t *)handle->data;
msgr->stop_callback(msgr);
}
void uv_messenger_stop(uv_messenger_t *msgr) {
void uv_messenger_stop(uv_messenger_t *msgr, uv_messenger_stop_cb stop_callback) {
assert(!msgr->stop_callback);
msgr->stop_callback = stop_callback;
uv_close((uv_handle_t *)&msgr->async, uv__messenger_stop_callback);
}

View File

@@ -18,6 +18,10 @@ struct uv__worker_thread_s {
uv_thread_t thread;
};
void uv__worker_free_messenger(uv_messenger_t *msgr) {
free(msgr);
}
void uv__worker_thread_finished(uv__worker_thread_t *worker_thread) {
uv_worker_t *worker = worker_thread->worker;
@@ -35,7 +39,7 @@ void uv__worker_thread_finished(uv__worker_thread_t *worker_thread) {
worker->count--;
if (worker->count == 0) {
uv_chan_destroy(&worker->chan);
uv_messenger_stop(worker->msgr);
uv_messenger_stop(worker->msgr, uv__worker_free_messenger);
if (worker->close_cb) {
worker->close_cb(worker);
}