Permalink
Browse files

Add fifo queue support to serialportWrite, fix test to detect arduino…

…s under Linux
  • Loading branch information...
JayBeavers committed Sep 4, 2012
1 parent d3701cf commit 39e559fc1127ae4bc93ffd3ef072a03a007d772d
Showing with 54 additions and 9 deletions.
  1. +35 −5 src/serialport.cpp
  2. +7 −0 src/serialport.h
  3. +2 −1 src/serialport_unix.cpp
  4. +2 −1 src/serialport_win.cpp
  5. 0 test/{ → echo}/echo.ino
  6. +8 −2 test/echoTest.js
View
@@ -5,9 +5,15 @@
#define strcasecmp stricmp
#endif
+uv_mutex_t write_queue_mutex;
+ngx_queue_t write_queue;
+
v8::Handle<v8::Value> Open(const v8::Arguments& args) {
v8::HandleScope scope;
+ uv_mutex_init(&write_queue_mutex);
+ ngx_queue_init(&write_queue);
+
// path
if(!args[0]->IsString()) {
return scope.Close(v8::ThrowException(v8::Exception::TypeError(v8::String::New("First argument must be a string"))));
@@ -97,15 +103,28 @@ v8::Handle<v8::Value> Write(const v8::Arguments& args) {
baton->bufferLength = bufferLength;
baton->callback = v8::Persistent<v8::Value>::New(callback);
- uv_work_t* req = new uv_work_t();
- req->data = baton;
- uv_queue_work(uv_default_loop(), req, EIO_Write, EIO_AfterWrite);
+ QueuedWrite* queuedWrite = new QueuedWrite();
+ memset(queuedWrite, 0, sizeof(QueuedWrite));
+ ngx_queue_init(&queuedWrite->queue);
+ queuedWrite->baton = baton;
+ queuedWrite->req.data = queuedWrite;
+
+ uv_mutex_lock(&write_queue_mutex);
+ bool empty = ngx_queue_empty(&write_queue);
+
+ ngx_queue_insert_tail(&write_queue, &queuedWrite->queue);
+
+ if (empty) {
+ uv_queue_work(uv_default_loop(), &queuedWrite->req, EIO_Write, EIO_AfterWrite);
+ }
+ uv_mutex_unlock(&write_queue_mutex);
return scope.Close(v8::Undefined());
}
void EIO_AfterWrite(uv_work_t* req) {
- WriteBaton* data = static_cast<WriteBaton*>(req->data);
+ QueuedWrite* queuedWrite = static_cast<QueuedWrite*>(req->data);
+ WriteBaton* data = static_cast<WriteBaton*>(queuedWrite->baton);
v8::Handle<v8::Value> argv[2];
if(data->errorString[0]) {
@@ -117,10 +136,21 @@ void EIO_AfterWrite(uv_work_t* req) {
}
v8::Function::Cast(*data->callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
+ uv_mutex_lock(&write_queue_mutex);
+ ngx_queue_remove(&queuedWrite->queue);
+
+ if (!ngx_queue_empty(&write_queue)) {
+ // Always pull the next work item from the head of the queue
+ ngx_queue_t* head = ngx_queue_head(&write_queue);
+ QueuedWrite* nextQueuedWrite = ngx_queue_data(head, QueuedWrite, queue);
+ uv_queue_work(uv_default_loop(), &nextQueuedWrite->req, EIO_Write, EIO_AfterWrite);
+ }
+ uv_mutex_unlock(&write_queue_mutex);
+
data->buffer.Dispose();
data->callback.Dispose();
delete data;
- delete req;
+ delete queuedWrite;
}
v8::Handle<v8::Value> Close(const v8::Arguments& args) {
View
@@ -77,6 +77,13 @@ struct WriteBaton {
char errorString[1024];
};
+struct QueuedWrite {
+public:
+ uv_work_t req;
+ ngx_queue_t queue;
+ WriteBaton* baton;
+};
+
struct CloseBaton {
public:
int fd;
View
@@ -203,7 +203,8 @@ void EIO_Open(uv_work_t* req) {
}
void EIO_Write(uv_work_t* req) {
- WriteBaton* data = static_cast<WriteBaton*>(req->data);
+ QueuedWrite* queuedWrite = static_cast<QueuedWrite*>(req->data);
+ WriteBaton* data = static_cast<WriteBaton*>(queuedWrite->baton);
int bytesWritten = write(data->fd, data->bufferData, data->bufferLength);
View
@@ -222,7 +222,8 @@ void AfterOpenSuccess(int fd, v8::Handle<v8::Value> dataCallback, v8::Handle<v8:
}
void EIO_Write(uv_work_t* req) {
- WriteBaton* data = static_cast<WriteBaton*>(req->data);
+ QueuedWrite* queuedWrite = static_cast<QueuedWrite*>(req->data);
+ WriteBaton* data = static_cast<WriteBaton*>(queuedWrite->baton);
OVERLAPPED ov = {0};
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
File renamed without changes.
View
@@ -17,6 +17,7 @@ describe('Echo', function() {
for (var i = 0; i < results.length; i++) {
var item = results[i];
+ // Under Windows this catches any Arduino that is loaded using the Teensyduino INF.
// Hardcoded to detect a Teensy INF device for now. Teensy INF works with Leonardo too.
if (item.manufacturer && item.manufacturer.indexOf('PJRC') != -1) {
portName = results[i].comName;
@@ -28,6 +29,12 @@ describe('Echo', function() {
portName = results[i].comName;
break;
}
+
+ // Under Ubuntu 12.04 this catches a Teensy.
+ if (item.pnpId && item.pnpId.indexOf('Teensy') != -1) {
+ portName = results[i].comName;
+ break;
+ }
}
console.log("Arduino found on " + portName);
@@ -89,13 +96,12 @@ describe('Echo', function() {
sendFrame('abc');
sendFrame('def');
- sendFrame('ghi');
+ sendFrame('ghi');
}
sp.on('open', function () {
setInterval(loop, 200);
});
-
});
});
});

0 comments on commit 39e559f

Please sign in to comment.