-
Notifications
You must be signed in to change notification settings - Fork 761
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
Fix QLocalSocket problem under Windows #2197
Fix QLocalSocket problem under Windows #2197
Conversation
For now, it fixes the Windows crash, so this should enable us to move the Windows development to master again, which we should try to do ASAP. Since QLocalSocket under Windows is unreliable (it might cut messages), it is not advised to use QDataStream. I have changed it to a messaging system based on strings and REs. At the beginning of each message we put the length of the message, so that the receiving side knows how much to retrieve. The change for now is only for the messages coming from SCProcess to sc_ipc_client direction. *I don't know if something similar needs to be done in the other direction, or where...*
@timblechmann, I could really use your input on this... I am not very familiar with what the QLocalSockets are used for, so I am not sure if this is enough... I think I have fixed the case for the updateText and updateSel selectors, that was crashing Windows, but I am not sure if I need to make the change somewhere else. I have tried to make the change as compact as possible, following your advice on the previous stab at fixing this. This is still using QLocalSocket, with some changes to make it usable under Windows. What do you think? Thanks in advance, |
QDataStream in ( &receivedData ); | ||
in.setVersion ( QDataStream::Qt_4_6 ); | ||
QString selector; | ||
static int readSize = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move the static variable to the class. static variables aren't free
my gut feeling tells me that regular expressions add quite some overhead and in a way i'd prefer to correctly this in qt ... and if this means enabling the wince workaround for localsockets for win32. afaict this was never raised to the qt developers and nobody actually checked if that workaround would be feasible. with your approach, every communication over the local sockets will have to be guarded in that way. one may also run into those issue when evaluating huge files ... personally i'd recommend to compile qt from sources and possibly provide qt binaries of recent qt version with qtwebkit enabled. but @llloret, as mentioned before i don't care about the community anymore, after people constantly complained to me about not caring about the community. so it's your call. |
Thanks for your input, @timblechmann, I really appreciate it. In case we wanted to pursue the approach I am taking... where else do you think I should makes this change? I am not sure what the LocalSockets are used for, really. I looked into doing the recompilation stuff, and I saw I had to change some Qt project files |
@llloret, local sockets are used for the communication between IDE and sclang. you might have to go through the sources to find the corresponding places (it has been a few years since jakob and me wrote that code, i'm not sure about all details). recompiling qt: it boils down to add one preprocessor definition. they seem to have a workaround in place, but only enable it for wince, but not for win32 ... qt takes a bit to compile, but in general the process is quite straight-forward once you have all the dependencies installed (https://doc.qt.io/qt-5/windows-building.html). |
@timblechmann, I think that the recompilation needs more than a preprocessor definition: from what I can see different files are put in SRC in Regarding reporting upstream... the thing is that I am not sure if this is a genuine bug, or just that it does not guarantee message oriented delivery, like TCP. That's why adding the length of the message at the beginning looks like a good solution (quite common on non message oriented protocols). |
But instead of doing the QDataStreamover the socket directly do it over a ByteArray, and prepend the length of the ByteArray, so that the receiver knows how much data to read
Ok, so I realized that I don't need the Regular Expression stuff. I can just use QDataStream over a QByteArray, instead of directly over the socket, and that way I know how much data I am writing, so I can put the size in front of the data. That way the receiving side knows how much to fetch and feed into a QDataStream to read it back. This makes the change even more compact, and more similar to the original. |
Create aux files to put some helper functions to help with LocalSockets. Add the new approach to the SingleGuardInstance case.
Hi, @timblechmann, what do you think of the current state of the changes now? I removed the Regular Expression stuff and went back to hte original approach, but instead of having the QDataStreams over the socket directly, I stream over a QByteArray first, to see the size and then send over the socket prepending the size. This way, the approach keeps the same spirit as your original implementation, just adding the size in front to deal with unreliable message boundaries. I have put some new auxiliary functions for this in a separate file. I think there is one more case to deal with, which is the introspection messages. I have already changed the SingleInstanceGuard, which required a very minor change. Will try to work on that later this week. |
But getting runtime warnings on setTextMirrorForDocument, so probably broke something
@@ -54,6 +54,7 @@ private Q_SLOTS: | |||
void updateDocText( const QVariantList & argList ); | |||
void updateDocSelection( const QVariantList & argList ); | |||
|
|||
int mReadSize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int mReadSize = 0;
... in-class initialiser are a bit more robust ... we have 2016, no need to use pre-c++11 constructs
quickly went through it ... looks much better now! |
Yep, once I realized that I could |
Ok, so I think that this is ready for more serious testing beyond me. So far I have tested it only on WIndows, and it looks good. I can try to do a Linux build, but not sure when. I can't test on Mac at all, so if someone could try that, it would be great. As I have already said, to me it is very important to get this on master ASAP to have Windows back into said master, and avoid desyncing again. So it would be great if we get some LGTMs or more feedback on this... |
Will test OS X as soon as I find a moment. Thanks luis and tim ! |
Brilliant, let me know how it goes. You will be the first one testing it on
Mac...(I don´t have one), so be patient...!.
|
Runs fine on OS X. I've just started the IDE, executed code, booted server, played some sounds. Anything odd I should test against ? There are no more regexp. ready to merge, ja ? |
Hi, I removed the regex approach, since I ended up using a more elegant and Great that it works on osx. Yes, I would merge this as soon as we can. At the moment I think it is one On Sat, 20 Aug 2016, 11:22 Chris Sattinger, notifications@github.com
|
Hi, It seems that this last commit breaks Linux builds at least for x86_64:
|
} | ||
|
||
QByteArray IntToArray(qint32 source) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't using Qt primitives in "common" break builds that have -DSC_QT=False
?
Yes, this breaks Linux and/or non-Qt builds: I see the same error as @aschneiderg |
Working here on Linux x86_64, SC_QT is on. |
@vivid-synth yes, it breaks non-Qt builds. Not being able to test Qt here as my repos use 5.6 which is known to not build. My params:
|
@@ -83,6 +83,7 @@ set(sclang_sources | |||
${CMAKE_SOURCE_DIR}/common/SC_StringBuffer.cpp | |||
${CMAKE_SOURCE_DIR}/common/SC_StringParser.cpp | |||
${CMAKE_SOURCE_DIR}/common/SC_TextUtils.cpp | |||
${CMAKE_SOURCE_DIR}/common/localsocket_utils.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we actually need this line? 'lang' seems not to have any changes: all the changes are in 'sc-ide'.
FWIW removing the above line from lang/CMakeLists.txt fixes the build on non-Qt installs, but I'd still also recommend we not keep anything Qt in "common". |
Ah nuts, sorry. I hope we can figure out a subsequent PR to restore that. I'm interested in a small nonqt build myself. |
I made changes to fix this but can't test: maybe someone with Qt can try?: #2299 |
Hi, is there something I should do here? I don't know what this non-qt build is... |
No, don't worry about it. @vivid-synth has nearly got it solved. non-qt build means building sclang without Qt - it is much smaller. we should have it in the travis test. maybe as the first one to get tested since it will build faster and fail faster. |
@crucialfelix very good idea; I've created a ticket: #2306 |
Still Work in Progress.
For now, it fixes the Windows crash, so this should enable us to move
the Windows development to master again, which we should try to do ASAP.
Since QLocalSocket under Windows is unreliable (it might cut messages),
it is not advised to use QDataStream.
I have changed it to a messaging system based on strings and REs. At the
beginning of each message I put the length of the message, so that the
receiving side knows how much to retrieve.
The change for now is only for the messages coming from SCProcess to
sc_ipc_client direction. I don't know if something similar needs to be
done in the other direction, or where..., please advise