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

Adding WindowsBinding reading #1018

Merged
merged 3 commits into from
Dec 10, 2016
Merged

Conversation

munyirik
Copy link

@reconbot I took a stab at #994 today.
I've only done minimal testing but I wanted to open the PR early and get your feedback.

Copy link
Member

@reconbot reconbot left a comment

Choose a reason for hiding this comment

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

Since we loop until we have some data we don't need to reque any more work.

@@ -681,6 +731,7 @@ extern "C" {
Nan::SetMethod(target, "open", Open);
Nan::SetMethod(target, "update", Update);
Nan::SetMethod(target, "write", Write);
Nan::SetMethod(target, "read", Read);
Copy link
Member

Choose a reason for hiding this comment

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

Should we move all of this to serialport_win.cpp

Copy link
Author

Choose a reason for hiding this comment

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

I'd like to leave it since serialport_uwp will also use it. I can use ifdef WIN32 since the macro is defined when UWP is used.

Copy link
Author

Choose a reason for hiding this comment

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

or maybe I could keep it in a 'common' cpp file. I could avoid using an ifdef if there was something like a SetExtraMethods() in the init function where native bindings could add extra methods (in this case read) or just do nothing. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

lets just ifdef win32 but make sure to put the after read in this file too

@@ -26,6 +26,10 @@ NAN_METHOD(Write);
void EIO_Write(uv_work_t* req);
void EIO_AfterWrite(uv_work_t* req);

NAN_METHOD(Read);
void EIO_Read(uv_work_t* req);
Copy link
Member

Choose a reason for hiding this comment

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

And this stuff inside an ifdef

if (data->errorString[0]) {
argv[0] = Nan::Error(data->errorString);
argv[1] = argv[2] = Nan::Undefined();
Sleep(100); // prevent the errors from occurring too fast
Copy link
Member

Choose a reason for hiding this comment

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

Is this left over from when we used to loop endlessly?

Copy link
Author

Choose a reason for hiding this comment

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

Yes. Is the sleep still needed? I didn't want to take it out in case it was there for a good reason.

Copy link
Member

Choose a reason for hiding this comment

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

Previously we'd emit c++ buffers as fast as we could, now we take a js buffer write to it and return. I can't imagine why we'd want to sleep. You have my blessing to rip out anything you don't understand.

} else {
argv[0] = Nan::Null();
argv[1] = Nan::New<v8::Integer>((int)data->bytesRead);
argv[2] = Nan::NewBuffer(data->bufferData, data->bufferLength, FinalizerCallback, req).ToLocalChecked();
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, we have a buffer from js land, this path seems not needed

Copy link
Author

Choose a reason for hiding this comment

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

I was following the readcallback signature. Should I just leave it undefined or is there a way to assign the buffer pointer to argv[2]? ...not sure how to do that.

Copy link
Author

Choose a reason for hiding this comment

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

You're right. That path isn't needed. I hadn't initially realized that the callback is actually the onRead function in push-methods :-|

@reconbot
Copy link
Member

👏👌

@@ -141,6 +145,17 @@ struct QueuedWrite {
}
};

struct ReadBaton {
int fd;
char* bufferData;
Copy link
Member

Choose a reason for hiding this comment

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

So I think the crux of the change will be to make this a pointer to a v8::Local<v8::Object> buffer object, that way we can pass it all the way through. Write to it and then pass it to the callback. I don't know how to write to a buffer as if it were a char[] maybe @indutny can throw us some pointers.

Copy link

Choose a reason for hiding this comment

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

I'd say Persistent rather than Local. Local is for something on-stack.

Munyiri Kamau added 2 commits November 21, 2016 16:30
- Fix CI failure to build
- Tests (including read) now pass locally
- Changes based on review feedback
@munyirik
Copy link
Author

munyirik commented Dec 9, 2016

@reconbot could you take a look at the latest updates when you get a chance.

Copy link
Member

@reconbot reconbot left a comment

Choose a reason for hiding this comment

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

Looking pretty good!

@Zensey brought up CreateIoCompletionPorts which should be on our radar for future PRs.

I'd like to land this soon =)

WindowsBinding.prototype.read = require('./read-unix');
WindowsBinding.prototype.read = function(buffer, offset, length, cb) {
if (!Buffer.isBuffer(buffer)) {
throw new TypeError('"buffer" is not a Buffer');
Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure your c++ throws would bubble up just fine for type checking

Copy link
Author

Choose a reason for hiding this comment

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

Yeah seems like overkill

argv[1] = Nan::Undefined();
} else {
argv[0] = Nan::Null();
argv[1] = Nan::New<v8::Integer>((int)data->bytesRead);
Copy link
Member

Choose a reason for hiding this comment

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

We should be calling the read callback with the buffer as the 3rd arg. The decision was to stay in party with fs.read.

Copy link
Author

Choose a reason for hiding this comment

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

Ok. I had left it out since the push-methods _read wasn't using that parameter - https://github.com/EmergingTechnologyAdvisors/node-serialport/blob/master/lib/push-methods.js#L31

DWORD bytesReadSync = 0;
if (!ReadFile((HANDLE)data->fd, offsetPtr, data->bytesToRead, &bytesReadSync, &ov)) {
errorCode = GetLastError();
if (errorCode != ERROR_IO_PENDING) {
Copy link
Member

Choose a reason for hiding this comment

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

might be worth looking at #1020

Copy link
Author

Choose a reason for hiding this comment

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

Thanks. I'll keep my eye on it. Looks like someone's still able to repro with the proposed fix.

@reconbot reconbot merged commit b80025e into serialport:master Dec 10, 2016
@reconbot
Copy link
Member

I realized the comments I made aren't blocking, so lets land this. =)

reconbot added a commit that referenced this pull request Jul 24, 2018
Adding WindowsBinding reading
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants