20 enum { maxHandles = 2 };
21 HANDLE handles[maxHandles];
22 DWORD handleCount = 0;
23 bool waitForClose =
false;
24 bool writePending =
false;
29 if (
socket.pipeWriter &&
socket.pipeWriter->isWriteOperationActive()) {
30 handles[handleCount++] =
socket.pipeWriter->syncEvent();
33 if (
socket.pipeReader->isReadOperationActive())
34 handles[handleCount++] =
socket.pipeReader->syncEvent();
41 const qint64 sleepTime = 10;
43 if (waitForClose && (remainingTime > sleepTime || remainingTime == -1))
67 waitRet = WaitForMultipleObjectsEx(handleCount, handles, FALSE,
69 }
while (waitRet == WAIT_IO_COMPLETION);
71 if (waitRet == WAIT_TIMEOUT)
74 return waitRet - WAIT_OBJECT_0 < handleCount;
83 this, &QLocalSocketPrivate::_q_canRead);
88void QLocalSocketPrivate::_q_winError(
ulong windowsError,
const QString &function)
95 windowsError = ERROR_NO_DATA;
97 switch (windowsError) {
98 case ERROR_PIPE_NOT_CONNECTED:
99 case ERROR_BROKEN_PIPE:
102 errorString = QLocalSocket::tr(
"%1: Connection error").
arg(function);
105 case ERROR_FILE_NOT_FOUND:
110 case ERROR_ACCESS_DENIED:
112 errorString = QLocalSocket::tr(
"%1: Access denied").
arg(function);
117 errorString = QLocalSocket::tr(
"%1: Unknown error %2").
arg(function).
arg(windowsError);
118#if defined QLOCALSOCKET_DEBUG
124 if (currentState !=
state) {
127 emit q->disconnected();
133 handle(INVALID_HANDLE_VALUE),
138 emittedReadyRead(
false),
139 emittedBytesWritten(
false)
143QLocalSocketPrivate::~QLocalSocketPrivate()
155 d->errorString =
tr(
"Trying to connect while connection is in progress");
164 if (
d->serverName.isEmpty()) {
166 d->errorString =
tr(
"%1: Invalid name").arg(
"QLocalSocket::connectToServer"_L1);
173 const auto pipePath =
"\\\\.\\pipe\\"_L1;
174 if (
d->serverName.startsWith(pipePath))
175 d->fullServerName =
d->serverName;
177 d->fullServerName = pipePath +
d->serverName;
183 localSocket = CreateFile(
reinterpret_cast<const wchar_t *
>(
d->fullServerName.utf16()),
188 FILE_FLAG_OVERLAPPED,
191 if (localSocket != INVALID_HANDLE_VALUE)
193 DWORD
error = GetLastError();
195 if (ERROR_PIPE_BUSY !=
error) {
200 if (!WaitNamedPipe((
const wchar_t *)
d->fullServerName.utf16(), 5000))
204 if (localSocket == INVALID_HANDLE_VALUE) {
205 const DWORD winError = GetLastError();
206 d->_q_winError(winError,
"QLocalSocket::connectToServer"_L1);
268 d->errorString =
tr(
"Socket is not connected");
275 if (!
d->pipeWriter) {
278 d, &QLocalSocketPrivate::_q_bytesWritten);
280 d, &QLocalSocketPrivate::_q_writeFailed);
283 if (
d->isWriteChunkCached(
data,
len))
284 d->pipeWriter->write(*(
d->currentWriteChunk));
295 delete d->pipeWriter;
301void QLocalSocketPrivate::_q_canRead()
304 if (!emittedReadyRead) {
310void QLocalSocketPrivate::_q_pipeClosed()
327 pipeWriter =
nullptr;
328 if (
handle != INVALID_HANDLE_VALUE) {
329 DisconnectNamedPipe(
handle);
331 handle = INVALID_HANDLE_VALUE;
336 emit q->readChannelFinished();
337 emit q->disconnected();
344 available +=
d->pipeReader->bytesAvailable();
351 return d->pipeWriterBytesToWrite();
365 d->pipeReader->stopAndClear();
375 return d->pipeWriter &&
d->pipeWriter->checkForWrite();
397 LocalSocketState socketState, OpenMode openMode)
400 d->pipeReader->stop();
402 d->state = socketState;
403 d->pipeReader->setHandle(
d->handle);
407 d->pipeReader->startAsyncRead();
411qint64 QLocalSocketPrivate::pipeWriterBytesToWrite()
const
413 return pipeWriter ? pipeWriter->bytesToWrite() :
qint64(0);
416void QLocalSocketPrivate::_q_bytesWritten(
qint64 bytes)
419 if (!emittedBytesWritten) {
421 emit q->bytesWritten(bytes);
424 q->disconnectFromServer();
427void QLocalSocketPrivate::_q_writeFailed()
440 return reinterpret_cast<qintptr>(
d->handle);
446 return d->pipeReader->maxReadBufferSize();
452 d->pipeReader->setMaxReadBufferSize(
size);
465 qWarning(
"QLocalSocket::waitForDisconnected() is not allowed in UnconnectedState");
470 bool wasChecked =
false;
471 while (!
d->pipeReader->isPipeClosed()) {
475 QSocketPoller poller(*
d);
478 if (!poller.writePending && poller.waitForClose) {
482 SleepEx(poller.getRemainingTime(
deadline), TRUE);
483 }
else if (!poller.poll(
deadline)) {
488 d->pipeWriter->checkForWrite();
492 if (poller.waitForClose &&
isValid())
493 d->pipeReader->checkPipeState();
495 d->pipeReader->checkForReadyRead();
505 return d->handle != INVALID_HANDLE_VALUE;
516 while (!
d->pipeReader->isPipeClosed()) {
517 QSocketPoller poller(*
d);
518 if (poller.waitForClose || !poller.poll(
deadline))
522 d->pipeWriter->checkForWrite();
524 if (
d->pipeReader->checkForReadyRead())
539 bool wasChecked =
false;
540 while (!
d->pipeReader->isPipeClosed()) {
544 QSocketPoller poller(*
d);
545 if (!poller.writePending || !poller.poll(
deadline))
549 if (
d->pipeWriter->checkForWrite())
552 if (poller.waitForClose &&
isValid())
553 d->pipeReader->checkPipeState();
555 d->pipeReader->checkForReadyRead();
bool hasExpired() const noexcept
Returns true if this QDeadlineTimer object has expired, false if there remains time left.
qint64 remainingTime() const noexcept
Returns the remaining time in this QDeadlineTimer object in milliseconds.
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
QIODeviceBase::OpenMode openMode() const
Returns the mode in which the device has been opened; i.e.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
virtual void close()
First emits aboutToClose(), then closes the device and sets its OpenMode to NotOpen.
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false.
QLocalSocket::LocalSocketState state
The QLocalSocket class provides a local socket.
bool setSocketDescriptor(qintptr socketDescriptor, LocalSocketState socketState=ConnectedState, OpenMode openMode=ReadWrite)
Initializes QLocalSocket with the native socket descriptor socketDescriptor.
void connected()
This signal is emitted after connectToServer() has been called and a connection has been successfully...
LocalSocketState state() const
Returns the state of the socket.
virtual qint64 readData(char *, qint64) override
\reimp
void abort()
Aborts the current connection and resets the socket.
virtual qint64 bytesToWrite() const override
\reimp
virtual bool canReadLine() const override
\reimp
bool waitForBytesWritten(int msecs=30000) override
\reimp
LocalSocketState
This enum describes the different states in which a socket can be.
bool isValid() const
Returns true if the socket is valid and ready for use; otherwise returns false.
bool flush()
This function writes as much as possible from the internal write buffer to the socket,...
LocalSocketError error() const
Returns the type of error that last occurred.
qint64 readBufferSize() const
Returns the size of the internal read buffer.
bool waitForDisconnected(int msecs=30000)
Waits until the socket has disconnected, up to msecs milliseconds.
void disconnectFromServer()
Attempts to close the socket.
qint64 readLineData(char *data, qint64 maxSize) override
\reimp
bool waitForConnected(int msecs=30000)
Waits until the socket is connected, up to msecs milliseconds.
bool waitForReadyRead(int msecs=30000) override
This function blocks until data is available for reading and the \l{QIODevice::}{readyRead()} signal ...
void connectToServer(OpenMode openMode=ReadWrite)
void setReadBufferSize(qint64 size)
Sets the size of QLocalSocket's internal read buffer to be size bytes.
qintptr socketDescriptor() const
Returns the native socket descriptor of the QLocalSocket object if this is available; otherwise retur...
virtual void close() override
Closes the I/O device for the socket and calls disconnectFromServer() to close the socket's connectio...
qint64 skipData(qint64 maxSize) override
\reimp
virtual qint64 bytesAvailable() const override
\reimp
void stateChanged(QLocalSocket::LocalSocketState socketState)
This signal is emitted whenever QLocalSocket's state changes.
virtual qint64 writeData(const char *, qint64) override
\reimp
LocalSocketError
The LocalServerError enumeration represents the errors that can occur.
void errorOccurred(QLocalSocket::LocalSocketError socketError)
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
\macro QT_RESTRICTED_CAST_FROM_ASCII
void clear()
Clears the contents of the string and makes it null.
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
int remainingTime
the remaining time in milliseconds
void bytesWritten(qint64 bytes)
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
static qint64 transformPipeReaderResult(qint64 res)
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
QDeadlineTimer deadline(30s)