Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor and modernize the native interface #35

Merged
merged 50 commits into from
Sep 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
92e1fd5
refactor the queue implementation
Sep 12, 2017
5ec8b6e
FIX: remove dependency to uv_sem_t in osx service
reneme Sep 12, 2017
4425157
extend CMakeLists.txt for platform dependent code
reneme Sep 12, 2017
62939cd
FIX: use const& of std::string
reneme Sep 12, 2017
b36a028
Merge pull request #1 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 12, 2017
3015c9d
FIX: usage of condition variable
reneme Sep 12, 2017
5fc4dbd
use the javascript tests with windows
Sep 12, 2017
2137636
Merge pull request #2 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 12, 2017
87b2e59
remove dependency to OpenPA
reneme Sep 12, 2017
28701c9
FIX: signed/unsigned compiler warning
reneme Sep 12, 2017
e91446e
Merge pull request #3 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 12, 2017
5d11a18
change xcode configuration for nodejs 4 and 6
Sep 12, 2017
5c7fe7d
try to find a reace cond
Sep 12, 2017
feb3b0e
try msvs 2015
Sep 12, 2017
e7a94c3
FIX: build on macOS with node.js v4
reneme Sep 13, 2017
bfe9eee
switch from c++0x to proper c++11
reneme Sep 13, 2017
4978e9a
Refactor: add a single shot semaphore for threadsafe state announcement
reneme Sep 13, 2017
747d16e
FIX: remove unnecessary implementation
reneme Sep 13, 2017
9c58e58
Merge pull request #4 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 13, 2017
438cf33
merge with origin/master
Sep 13, 2017
ed56d42
FIX: code cosmetics
reneme Sep 13, 2017
a65bca5
Merge remote-tracking branch 'xqp/refactor/remove_opa_and_use_cpp11_S…
reneme Sep 13, 2017
1e667d0
refactor the windows native implementation
Sep 13, 2017
422d46b
implement error handling in watcher and controller
Sep 13, 2017
def8e5a
use c++11 threads instead of native implementation
Sep 13, 2017
5352ae8
quickfix for windows js tests
Sep 13, 2017
94156e7
FIX: linux and macOS with std::shared_ptr<EventQueue>
reneme Sep 13, 2017
f5f6caa
Merge pull request #5 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 14, 2017
ce29e83
fix deadlock in nodejs cpp interface
Sep 14, 2017
72459d6
delete unused files
Sep 14, 2017
31e3c18
move files and cleanup files
Sep 14, 2017
cd10116
revert some changes
Sep 14, 2017
85b10b3
Refactor: remove the self-tailored lock guard
reneme Sep 14, 2017
7d6779f
Doc: SingleshotSemaphore
reneme Sep 14, 2017
daa2e52
FIX: cosmetics
reneme Sep 14, 2017
60ade73
Merge pull request #6 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 14, 2017
27d1677
Refactor: use std::thread rather then pthread_t
reneme Sep 14, 2017
da6e002
Merge pull request #7 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 14, 2017
0a8befa
use semaphore to wait until thread is running
Sep 14, 2017
f224dbf
Merge pull request #8 from hrantzsch/refactor/remove_opa_and_use_cpp1…
Sep 14, 2017
c159680
review issues
Sep 20, 2017
6daa85f
Merge branch 'refactor/remove_opa_and_use_cpp11_STL' of https://githu…
Sep 20, 2017
7cd1053
style guide issue
Sep 20, 2017
2674f64
upgrade to msvc 2015 because compile error in older version
Sep 20, 2017
b782c47
FIX: review comments
reneme Sep 22, 2017
b651b28
Merge pull request #9 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 22, 2017
f3a859c
FIX: missing header adaption
reneme Sep 22, 2017
a9aa805
Merge pull request #10 from reneme/refactor/remove_opa_and_use_cpp11_STL
Sep 22, 2017
01f1a75
fix compile errors in windows ci build
Sep 22, 2017
990cafb
remove empty line in cmakelists
Sep 22, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake_minimum_required (VERSION 3.1.0 FATAL_ERROR)
set (PROJECT_NAME "NSFW")
project (${PROJECT_NAME})

message (STATUS "Running CMake version ${CMAKE_VERSION}")

set (NSFW_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")

add_subdirectory (src)
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
# install modules
- npm install --msvs_version=2013
- npm install --msvs_version=2015
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this still build with msvs_version set to 2013?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let us use the 2013 compiler :)


# Post-install test scripts.
test_script:
Expand Down
40 changes: 12 additions & 28 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
"targets": [{
"target_name": "nsfw",

"dependencies": [
"openpa/openpa.gyp:openpa"
],

"sources": [
"src/NSFW.cpp",
"src/Queue.cpp",
Expand All @@ -22,10 +18,10 @@
"conditions": [
["OS=='win'", {
"sources": [
"src/win32/ReadLoop.cpp",
"src/win32/ReadLoopRunner.cpp",
"includes/win32/ReadLoop.h",
"includes/win32/ReadLoopRunner.h"
"src/win32/Controller.cpp",
"src/win32/Watcher.cpp",
"includes/win32/Controller.h",
"includes/win32/Watcher.h"
],
"msvs_settings": {
"VCCLCompilerTool": {
Expand All @@ -38,13 +34,18 @@
}],
["OS=='mac'", {
"sources": [
"src/Lock.cpp",
"src/osx/RunLoop.cpp",
"src/osx/FSEventsService.cpp",
"includes/Lock.h",
"includes/osx/RunLoop.h",
"includes/osx/FSEventsService.h"
],
"xcode_settings": {
'MACOSX_DEPLOYMENT_TARGET': '10.7',
"OTHER_CFLAGS": [
"-std=c++11",
"-stdlib=libc++"
],
},
"link_settings": {
"xcode_settings": {
"OTHER_LDFLAGS": [
Expand All @@ -58,25 +59,19 @@
}],
["OS=='linux' or OS=='freebsd'", {
"sources": [
"src/Lock.cpp",
"src/linux/InotifyEventLoop.cpp",
"src/linux/InotifyTree.cpp",
"src/linux/InotifyService.cpp",
"includes/Lock.h",
"includes/linux/InotifyEventLoop.h",
"includes/linux/InotifyTree.h",
"includes/linux/InotifyService.h"
],
"cflags": [
"-Wno-unknown-pragmas",
"-std=c++0x"
"-std=c++11"
]
}],
["OS=='win'", {
"defines": [
"OPA_HAVE_NT_INTRINSICS=1",
"_opa_inline=__inline"
],
"conditions": [
["target_arch=='x64'", {
"VCLibrarianTool": {
Expand All @@ -95,7 +90,6 @@
}],
["OS=='mac' or OS=='linux' or OS=='freebsd'", {
"defines": [
"OPA_HAVE_GCC_INTRINSIC_ATOMICS=1",
"HAVE_STDDEF_H=1",
"HAVE_STDLIB_H=1",
"HAVE_UNISTD_H=1"
Expand All @@ -106,16 +100,6 @@
"/usr/local/include"
]
}],
["target_arch=='x64' or target_arch=='arm64'", {
"defines": [
"OPA_SIZEOF_VOID_P=8"
]
}],
["target_arch=='ia32' or target_arch=='armv7'", {
"defines": [
"OPA_SIZEOF_VOID_P=4"
]
}]
]
}]
}
14 changes: 0 additions & 14 deletions includes/Lock.h

This file was deleted.

5 changes: 3 additions & 2 deletions includes/NSFW.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <nan.h>
#include <uv.h>
#include <vector>
#include <atomic>

using namespace Nan;

Expand All @@ -28,7 +29,7 @@ class NSFW : public ObjectWrap {
bool mInterfaceLockValid;
std::string mPath;
uv_thread_t mPollThread;
bool mRunning;
std::atomic<bool> mRunning;
private:
NSFW(uint32_t debounceMS, std::string path, Callback *eventCallback, Callback *errorCallback);
~NSFW();
Expand All @@ -40,7 +41,7 @@ class NSFW : public ObjectWrap {

struct EventBaton {
NSFW *nsfw;
std::vector<Event *> *events;
std::vector<Event*> *events;
};

static NAN_METHOD(JSNew);
Expand Down
21 changes: 16 additions & 5 deletions includes/NativeInterface.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
#ifndef NSFW_NATIVE_INTERFACE_H
#define NSFW_NATIVE_INTERFACE_H

#if defined(_WIN32)
#include "../includes/win32/Controller.h"
using NativeImplementation = Controller;
#elif defined(__APPLE_CC__)
#include "../includes/osx/FSEventsService.h"
using NativeImplementation = FSEventsService;
#elif defined(__linux__) || defined(__FreeBSD__)
#include "../includes/linux/InotifyService.h"
using NativeImplementation = InotifyService;
#endif

#include "Queue.h"
#include <vector>

class NativeInterface {
public:
NativeInterface(std::string path);
NativeInterface(const std::string &path);
~NativeInterface();

std::string getError();
std::vector<Event *> *getEvents();
std::vector<Event*> *getEvents();
bool hasErrored();
bool isWatching();

~NativeInterface();
private:
EventQueue mQueue;
void *mNativeInterface;
std::shared_ptr<EventQueue> mQueue;
std::unique_ptr<NativeImplementation> mNativeInterface;
};

#endif
32 changes: 14 additions & 18 deletions includes/Queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
#define NSFW_QUEUE_H

#include <string>
extern "C" {
# include <opa_queue.h>
# include <opa_primitives.h>
}
#include <memory>
#include <deque>
#include <vector>
#include <mutex>

enum EventType {
CREATED = 0,
Expand All @@ -15,32 +15,28 @@ enum EventType {
};

struct Event {
Event(const EventType type, const std::string &directory, const std::string &fileA, const std::string &fileB) :
type(type), directory(directory), fileA(fileA), fileB(fileB) {}
EventType type;
std::string directory, fileA, fileB;
};

class EventQueue {
public:
EventQueue();
~EventQueue();

void clear();
int count();
Event *dequeue(); // Free this pointer when you are done with it
std::size_t count();
std::unique_ptr<Event> dequeue();
std::unique_ptr<std::vector<Event*>> dequeueAll();
void enqueue(
EventType type,
std::string directory,
std::string fileA,
std::string fileB = ""
const std::string &directory,
const std::string &fileA,
const std::string &fileB = ""
);

private:
struct EventNode {
OPA_Queue_element_hdr_t header;
Event *event;
};
OPA_Queue_info_t mQueue;
OPA_int_t mNumEvents;
std::deque<std::unique_ptr<Event>> queue;
std::mutex mutex;
};

#endif
67 changes: 67 additions & 0 deletions includes/SingleshotSemaphore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef NSFW_SEMAPHORE_H
#define NSFW_SEMAPHORE_H

#include <condition_variable>
#include <mutex>

/**
* This is a convenience abstraction around std::condition_variable that allows
* for a one-shot synchronization point. Therefore the Semaphore has no way to
* reset its state.
*
* It doesn't matter if the waiting thread calls `wait()` before or after the
* signaling thread calls `signal()`. Only in the latter case the `wait()` won't
* block.
*/
class SingleshotSemaphore {
public:
SingleshotSemaphore() : mState(false) {}

/**
* Blocks the calling thread until the semaphore is signaled asynchronously.
* If `signal()` has been called on the semaphore already, this won't block.
*/
void wait() {
std::unique_lock<std::mutex> lk(mMutex);

while (!mState) {
mCond.wait(lk);
}
}

/**
* Blocks the calling thread for a given time period and continues either
* when `signal()` was called asynchronously or when the time is up. The
* return condition is indicated by the returned boolean.
*
* \return true if the semaphore was signal()ed; false on timeout reached
*/
bool waitFor(std::chrono::milliseconds ms) {
std::unique_lock<std::mutex> lk(mMutex);

if (mState) {
return true;
}

mCond.wait_for(lk, ms);
return mState;
}

/**
* Unblocks all waiting threads of the semaphore. Note that threads reaching
* the `wait()` on this semaphore after `signal()` has been called won't
* block but continue immediately.
*/
void signal() {
std::unique_lock<std::mutex> lk(mMutex);
mState = true;
mCond.notify_all();
}

private:
std::mutex mMutex;
std::condition_variable mCond;
bool mState;
};

#endif
7 changes: 5 additions & 2 deletions includes/linux/InotifyEventLoop.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
#define INOTIFY_EVENT_LOOP_H

#include "InotifyService.h"
#include "../Lock.h"
#include "../SingleshotSemaphore.h"

#include <sys/inotify.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/select.h>
#include <string>
#include <mutex>

class InotifyService;
class Lock;
Expand Down Expand Up @@ -40,7 +42,8 @@ class InotifyEventLoop {
InotifyService *mInotifyService;

pthread_t mEventLoop;
pthread_mutex_t mMutex;
std::mutex mMutex;
SingleshotSemaphore mLoopingSemaphore;
bool mStarted;
};

Expand Down
4 changes: 2 additions & 2 deletions includes/linux/InotifyService.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class InotifyTree;

class InotifyService {
public:
InotifyService(EventQueue &queue, std::string path);
InotifyService(std::shared_ptr<EventQueue> queue, std::string path);

std::string getError();
bool hasErrored();
Expand All @@ -32,7 +32,7 @@ class InotifyService {
void renameDirectory(int wd, std::string oldName, std::string newName);

InotifyEventLoop *mEventLoop;
EventQueue &mQueue;
std::shared_ptr<EventQueue> mQueue;
InotifyTree *mTree;
int mInotifyInstance;

Expand Down
4 changes: 2 additions & 2 deletions includes/osx/FSEventsService.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class RunLoop;

class FSEventsService {
public:
FSEventsService(EventQueue &queue, std::string path);
FSEventsService(std::shared_ptr<EventQueue> queue, std::string path);

friend void FSEventsServiceCallback(
ConstFSEventStreamRef streamRef,
Expand All @@ -50,7 +50,7 @@ class FSEventsService {

std::string mPath;
RunLoop *mRunLoop;
EventQueue &mQueue;
std::shared_ptr<EventQueue> mQueue;
};

#endif
Loading