Created
May 9, 2012 01:56
-
-
Save jadonk/2641172 to your computer and use it in GitHub Desktop.
Why does the node.js module only see every 4th event?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <fcntl.h> | |
| #include <unistd.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| #include <stdlib.h> | |
| #include <sys/epoll.h> | |
| #include <sys/types.h> | |
| #include <ev.h> | |
| int fd, epfd; | |
| struct ev_io ew; | |
| void event(EV_P_ ev_io *w, int revents) | |
| { | |
| int n; | |
| char buf[64]; | |
| if(revents == EV_READ) { | |
| n = lseek(fd, 0, SEEK_SET); | |
| printf("seek %d bytes: %s\n", n, strerror(errno)); | |
| n = read(fd, &buf, 63); | |
| printf("read %d bytes: %s\n", n, strerror(errno)); | |
| buf[n] = 0; | |
| printf("buf = %s\n", buf); | |
| } else { | |
| printf("revents = %d\n", revents); | |
| } | |
| } | |
| int main(int argc, char** argv) { | |
| int n; | |
| epfd = epoll_create(1); | |
| fd = open("/sys/class/gpio/gpio34/value", O_RDWR | O_NONBLOCK); | |
| printf("open returned %d: %s\n", fd, strerror(errno)); | |
| if(fd > 0) { | |
| struct epoll_event ev; | |
| struct epoll_event events; | |
| ev.events = EPOLLPRI; | |
| ev.data.fd = fd; | |
| n = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev); | |
| printf("epoll_ctl returned %d: %s\n", n, strerror(errno)); | |
| ev_init(&ew, event); | |
| ev_io_set(&ew, epfd, EV_READ); | |
| ev_io_start(EV_DEFAULT_ &ew); | |
| ev_run(EV_DEFAULT_ 0); | |
| } | |
| return(0); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <v8.h> | |
| #include <node.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <fcntl.h> | |
| #include <sys/epoll.h> | |
| #include <sys/types.h> | |
| #include <stdio.h> | |
| #include <errno.h> | |
| #define PRINTF printf | |
| using namespace std; | |
| using namespace node; | |
| using namespace v8; | |
| extern "C" void init(Handle<Object>); | |
| static void pollpri_event(EV_P_ ev_io * req, int revents); | |
| #define QUOTE(name, ...) #name | |
| #define STR(macro) QUOTE(macro) | |
| #define TEST_EV_DEFAULT_NAME STR(EV_DEFAULT_) | |
| class Pollpri: ObjectWrap { | |
| private: | |
| int fd, epfd; | |
| char *path; | |
| public: | |
| ev_io event_watcher, *ew; | |
| static Persistent<FunctionTemplate> ct; | |
| static void Init(Handle<Object> target) { | |
| PRINTF("Entering Init\n"); | |
| HandleScope scope; | |
| Local<FunctionTemplate> t = FunctionTemplate::New(New); | |
| ct = Persistent<FunctionTemplate>::New(t); | |
| ct->InstanceTemplate()->SetInternalFieldCount(1); | |
| ct->SetClassName(String::NewSymbol("Pollpri")); | |
| target->Set(String::NewSymbol("Pollpri"), ct->GetFunction()); | |
| PRINTF("EV_DEFAULT_ = %s\n", TEST_EV_DEFAULT_NAME); | |
| PRINTF("Leaving Init\n"); | |
| } | |
| Pollpri() { | |
| PRINTF("Entering Pollpri constructor\n"); | |
| epfd = 0; | |
| fd = 0; | |
| ev_init(&event_watcher, pollpri_event); | |
| event_watcher.data = this; | |
| ew = &event_watcher; | |
| } | |
| ~Pollpri() { | |
| PRINTF("Entering Pollpri destructor\n"); | |
| if(epfd) close(epfd); | |
| if(fd) close(fd); | |
| } | |
| static Handle<Value> New(const Arguments& args) { | |
| PRINTF("Entered New\n"); | |
| HandleScope scope; | |
| const char *usage = "usage: new Pollpri(path)"; | |
| if(!args.IsConstructCall() || args.Length() != 1) { | |
| return ThrowException(Exception::Error(String::New(usage))); | |
| } | |
| String::Utf8Value path(args[0]); | |
| Pollpri *p = new Pollpri(); | |
| p->Wrap(args.This()); | |
| p->path = (char *)malloc(path.length() + 1); | |
| strncpy(p->path, *path, path.length() + 1); | |
| // Open file to watch | |
| int fd = open(p->path, O_RDWR | O_NONBLOCK); | |
| PRINTF("open(%s) returned %d: %s\n", p->path, fd, strerror(errno)); | |
| // Create epoll event | |
| int epfd = epoll_create(1); | |
| PRINTF("epoll_create(1) returned %d: %s\n", epfd, strerror(errno)); | |
| struct epoll_event ev; | |
| ev.events = EPOLLPRI; | |
| ev.data.fd = fd; | |
| int n = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev); | |
| PRINTF("epoll_ctl(%d) returned %d (%d): %s\n", fd, n, epfd, strerror(errno)); | |
| // Read initial state | |
| int m = 0; | |
| char buf[64]; | |
| m = lseek(fd, 0, SEEK_SET); | |
| PRINTF("seek(%d) %d bytes: %s\n", fd, m, strerror(errno)); | |
| m = read(fd, &buf, 63); | |
| buf[m] = 0; | |
| PRINTF("read(%d) %d bytes (%s): %s\n", fd, m, buf, strerror(errno)); | |
| // Setup event watcher | |
| ev_io_set(p->ew, epfd, EV_READ); | |
| ev_io_start(EV_DEFAULT_ p->ew); | |
| p->epfd = epfd; | |
| p->fd = fd; | |
| PRINTF("Leaving New\n"); | |
| return(args.This()); | |
| } | |
| void Event(Pollpri * p, int revents) { | |
| HandleScope scope; | |
| PRINTF("fd = %d, epfd = %d, revents = 0x%0x\n", fd, epfd, revents); | |
| if(revents != EV_READ) { | |
| return; | |
| } | |
| int m = 0; | |
| char buf[64]; | |
| m = lseek(fd, 0, SEEK_SET); | |
| PRINTF("seek(%d) %d bytes: %s\n", fd, m, strerror(errno)); | |
| m = read(fd, &buf, 63); | |
| buf[m] = 0; | |
| PRINTF("read(%d) %d bytes (%s): %s\n", fd, m, buf, strerror(errno)); | |
| Local<Value> emit_v = handle_->Get(String::NewSymbol("emit")); | |
| assert(emit_v->IsFunction()); | |
| Local<Function> emit_f = emit_v.As<Function>(); | |
| Handle<Value> argv[2]; | |
| argv[0] = String::New("edge"); | |
| argv[1] = String::New(buf); | |
| TryCatch tc; | |
| emit_f->Call(handle_, 2, argv); | |
| if(tc.HasCaught()) { | |
| FatalException(tc); | |
| } | |
| } | |
| static void pollpri_event(EV_P_ ev_io * req, int revents) { | |
| PRINTF("Entered pollpri_event\n"); | |
| Pollpri *p = static_cast<Pollpri*>(req->data); | |
| p->Event(p, revents); | |
| PRINTF("Leaving pollpri_event\n"); | |
| } | |
| }; | |
| Persistent<FunctionTemplate> Pollpri::ct; | |
| extern "C" { | |
| void init(Handle<Object> target) { | |
| PRINTF("Calling Init\n"); | |
| Pollpri::Init(target); | |
| } | |
| NODE_MODULE(pollpri, init); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment