void QNetworkReplyImplPrivate::_q_startOperation() { // ensure this function is only being called once if (state == Working) { qDebug("QNetworkReplyImpl::_q_startOperation was called more than once"); return; } state = Working; // note: if that method is called directly, it cannot happen that the backend is 0, // because we just checked via a qobject_cast that we got a http backend (see // QNetworkReplyImplPrivate::setup()) if (!backend) { error(QNetworkReplyImpl::ProtocolUnknownError, QCoreApplication::translate("QNetworkReply", "Protocol \"%1\" is unknown").arg(url.scheme())); // not really true!; finished(); return; } #ifndef QT_NO_BEARERMANAGEMENT if (!backend->start()) { // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call reply->backend->start() again for us when the session // state changes. state = WaitingForSession; QNetworkSession *session = manager->d_func()->networkSession; if (session) { Q_Q(QNetworkReplyImpl); QObject::connect(session, SIGNAL(error(QNetworkSession::SessionError)), q, SLOT(_q_networkSessionFailed())); if (!session->isOpen()) session->open(); } else { qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); } return; } #endif if (state != Finished) { if (operation == QNetworkAccessManager::GetOperation) pendingNotifications.append(NotifyDownstreamReadyWrite); handleNotifications(); } }
void QNetworkReplyImplPrivate::_q_startOperation() { Q_Q(QNetworkReplyImpl); // ensure this function is only being called once if (state == Working || state == Finished) { qDebug("QNetworkReplyImpl::_q_startOperation was called more than once"); return; } state = Working; // note: if that method is called directly, it cannot happen that the backend is 0, // because we just checked via a qobject_cast that we got a http backend (see // QNetworkReplyImplPrivate::setup()) if (!backend) { error(QNetworkReplyImpl::ProtocolUnknownError, QCoreApplication::translate("QNetworkReply", "Protocol \"%1\" is unknown").arg(url.scheme())); // not really true!; finished(); return; } #ifndef QT_NO_BEARERMANAGEMENT // Do not start background requests if they are not allowed by session policy QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession()); QVariant isBackground = backend->request().attribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(false)); if (isBackground.toBool() && session && session->usagePolicies().testFlag(QNetworkSession::NoBackgroundTrafficPolicy)) { error(QNetworkReply::BackgroundRequestNotAllowedError, QCoreApplication::translate("QNetworkReply", "Background request not allowed.")); finished(); return; } #endif if (!backend->start()) { #ifndef QT_NO_BEARERMANAGEMENT // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call _q_startOperation again for us when the session // state changes. state = WaitingForSession; if (session) { QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)), q, SLOT(_q_networkSessionFailed())); if (!session->isOpen()) { session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground); session->open(); } } else { qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); state = Working; error(QNetworkReplyImpl::NetworkSessionFailedError, QCoreApplication::translate("QNetworkReply", "Network session error.")); finished(); } #else qWarning("Backend start failed"); state = Working; error(QNetworkReplyImpl::UnknownNetworkError, QCoreApplication::translate("QNetworkReply", "backend start error.")); finished(); #endif return; } #ifndef QT_NO_BEARERMANAGEMENT if (session) { //get notification of policy changes. QObject::connect(session.data(), SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)), q, SLOT(_q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies))); } #endif // Prepare timer for progress notifications downloadProgressSignalChoke.start(); uploadProgressSignalChoke.invalidate(); if (backend && backend->isSynchronous()) { state = Finished; q_func()->setFinished(true); } else { if (state != Finished) { if (operation == QNetworkAccessManager::GetOperation) pendingNotifications.append(NotifyDownstreamReadyWrite); handleNotifications(); } } }
static void* vs_sync_inotify_handler(void* unused) { int rc; fd_set fdset; struct fdset_info master_fdset; struct timeval timeout; VPLTime_t wait_queue_delay = VPLTIME_INVALID; FD_ZERO(&master_fdset.fdset); master_fdset.maxfd = 0; FD_ZERO(&fdset); FD_SET(g_sync_inotify_pipe[0], &master_fdset.fdset); master_fdset.maxfd = g_sync_inotify_pipe[0]; while(1) { fdset = master_fdset.fdset; rc = select(master_fdset.maxfd + 1, &fdset, NULL, NULL, (wait_queue_delay == VPLTIME_INVALID) ? NULL : &timeout); if(rc == -1) { int err = errno; if(err == EBADF) { VPL_REPORT_INFO("Connection must have just closed. Got EBADF. Wait for rebuild signal on pipe."); FD_ZERO(&master_fdset.fdset); FD_SET(g_sync_inotify_pipe[0], &master_fdset.fdset); master_fdset.maxfd = g_sync_inotify_pipe[0]; continue; } else if(err == EINTR) { // Debug gprof profiling would interrupt the select call, simply try again continue; } else { VPL_REPORT_FATAL("Select call error: %s(%d).", strerror(err), err); return NULL; } } handleNotifications(fdset, VPLTime_GetTime(), wait_queue_delay); if(wait_queue_delay != VPLTIME_INVALID){ timeout.tv_sec = VPLTIME_TO_SEC(wait_queue_delay); timeout.tv_usec = wait_queue_delay - VPLTIME_FROM_SEC(timeout.tv_sec); } // Check notify pipe for orders // Quit loop on stop order // Anything else, just eat it. char cmd = '\0'; int err = 0; do { // LOG_DEBUG("Reading sync_inotify pipe..."); rc = read(g_sync_inotify_pipe[0], &cmd, 1); if(rc == -1) err = errno; // LOG_DEBUG("Read sync_inotify pipe. rc:%d(%d), cmd:%c", // rc, err, cmd); if(rc == 0) { // no more messages at EOF. break; } else if(rc == 1) { // Got a message. FdInotifyMap::const_iterator mapIter; switch(cmd) { case SYNC_INOTIFY_STOP: VPL_REPORT_INFO("Sync inotify stop. time to go..."); vs_sync_inotify_remove_all(); return NULL; break; case SYNC_INOTIFY_REFRESH: // handle updated sockets after pipe is empty. FD_ZERO(&master_fdset.fdset); FD_SET(g_sync_inotify_pipe[0], &master_fdset.fdset); master_fdset.maxfd = g_sync_inotify_pipe[0]; VPLMutex_Lock(VPLLazyInitMutex_GetMutex(&g_sync_inotify_mutex)); mapIter = g_fdInotifyMap.begin(); for(; mapIter != g_fdInotifyMap.end(); ++mapIter) { FD_SET((*mapIter).first, &master_fdset.fdset); if((*mapIter).first > master_fdset.maxfd) { master_fdset.maxfd = (*mapIter).first; } } VPLMutex_Unlock(VPLLazyInitMutex_GetMutex(&g_sync_inotify_mutex)); break; default: // Handle outbound requests after pipe is empty. break; } } else { // Got an error. if(err == EAGAIN || err == EINTR) { // no big deal break; } else { VPL_REPORT_WARN("Got error %s(%d) reading notify pipe:%d.", strerror(err), err, rc); vs_sync_inotify_remove_all(); return NULL; } } } while(rc == 1); } return NULL; }