bool JackClientPipeThread::Execute()
{
    try {

        jack_log("JackClientPipeThread::Execute %x", this);
        JackRequest header;
        int res = header.Read(fPipe);
        bool ret = true;

        // Lock the global mutex
        if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED) {
            jack_error("JackClientPipeThread::Execute : mutex wait error");
        }

        // Decode header
        if (res < 0) {
            jack_log("JackClientPipeThread::Execute : cannot decode header");
            ClientKill();
            ret = false;
        // Decode request
        } else if (fDecoder->HandleRequest(fPipe, header.fType) < 0) {
            ret = false;
        }

        // Unlock the global mutex
        if (!ReleaseMutex(fMutex)) {
            jack_error("JackClientPipeThread::Execute : mutex release error");
        }
        return ret;

    } catch (JackQuitException& e) {
        jack_log("JackClientPipeThread::Execute : JackQuitException");
        return false;
    }
}
Exemplo n.º 2
0
bool JackSocketServerChannel::Execute()
{
    try {

        // Global poll
        if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
            jack_error("JackSocketServerChannel::Execute : engine poll failed err = %s request thread quits...", strerror(errno));
            return false;
        } else {

            // Poll all clients
            for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
                int fd = fPollTable[i].fd;
                jack_log("JackSocketServerChannel::Execute : fPollTable i = %ld fd = %ld", i, fd);
                if (fPollTable[i].revents & ~POLLIN) {
                    jack_log("JackSocketServerChannel::Execute : poll client error err = %s", strerror(errno));
                    ClientKill(fd);
                } else if (fPollTable[i].revents & POLLIN) {
                    JackClientSocket* socket = fSocketTable[fd].second;
                    // Decode header
                    JackRequest header;
                    if (header.Read(socket) < 0) {
                        jack_log("JackSocketServerChannel::Execute : cannot decode header");
                        ClientKill(fd);
                    // Decode request
                    } else {
                        // Result is not needed here
                        fDecoder->HandleRequest(socket, header.fType);
                    }
                }
            }

            // Check the server request socket */
            if (fPollTable[0].revents & POLLERR) {
                jack_error("Error on server request socket err = %s", strerror(errno));
            }

            if (fPollTable[0].revents & POLLIN) {
                ClientCreate();
            }
        }

        BuildPoolTable();
        return true;

    } catch (JackQuitException& e) {
        jack_log("JackSocketServerChannel::Execute : JackQuitException");
        return false;
    }
}
int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* socket, int type_aux)
{
    JackRequest::RequestType type = (JackRequest::RequestType)type_aux;

    // Read data
    switch (type) {

        case JackRequest::kClientCheck: {
            jack_log("JackRequest::ClientCheck");
            JackClientCheckRequest req;
            JackClientCheckResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
            CheckWriteName("JackRequest::ClientCheck", socket);
            // Atomic ClientCheck followed by ClientOpen on same socket
            if (req.fOpen) {
                JackRequest header;
                header.Read(socket);
                return HandleRequest(socket, header.fType);
            }
            break;
        }

        case JackRequest::kClientOpen: {
            jack_log("JackRequest::ClientOpen");
            JackClientOpenRequest req;
            JackClientOpenResult res;
            CheckRead(req, socket);
            fHandler->ClientAdd(socket, &req, &res);
            CheckWriteName("JackRequest::ClientOpen", socket);
            break;
        }

        case JackRequest::kClientClose: {
            jack_log("JackRequest::ClientClose");
            JackClientCloseRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
            CheckWriteRefNum("JackRequest::ClientClose", socket);
            fHandler->ClientRemove(socket, req.fRefNum);
            // Will cause the wrapping thread to stop
            return -1;
        }

        case JackRequest::kActivateClient: {
            JackActivateRequest req;
            JackResult res;
            jack_log("JackRequest::ActivateClient");
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
            CheckWriteRefNum("JackRequest::ActivateClient", socket);
            break;
        }

        case JackRequest::kDeactivateClient: {
            jack_log("JackRequest::DeactivateClient");
            JackDeactivateRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
            CheckWriteRefNum("JackRequest::DeactivateClient", socket);
            break;
        }

        case JackRequest::kRegisterPort: {
            jack_log("JackRequest::RegisterPort");
            JackPortRegisterRequest req;
            JackPortRegisterResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
            CheckWriteRefNum("JackRequest::RegisterPort", socket);
            break;
        }

        case JackRequest::kUnRegisterPort: {
            jack_log("JackRequest::UnRegisterPort");
            JackPortUnRegisterRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
            CheckWriteRefNum("JackRequest::UnRegisterPort", socket);
            break;
        }

        case JackRequest::kConnectNamePorts: {
            jack_log("JackRequest::ConnectNamePorts");
            JackPortConnectNameRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
            CheckWriteRefNum("JackRequest::ConnectNamePorts", socket);
            break;
        }

        case JackRequest::kDisconnectNamePorts: {
            jack_log("JackRequest::DisconnectNamePorts");
            JackPortDisconnectNameRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
            CheckWriteRefNum("JackRequest::DisconnectNamePorts", socket);
            break;
        }

        case JackRequest::kConnectPorts: {
            jack_log("JackRequest::ConnectPorts");
            JackPortConnectRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
            CheckWriteRefNum("JackRequest::ConnectPorts", socket);
            break;
        }

        case JackRequest::kDisconnectPorts: {
            jack_log("JackRequest::DisconnectPorts");
            JackPortDisconnectRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
            CheckWriteRefNum("JackRequest::DisconnectPorts", socket);
            break;
        }

        case JackRequest::kPortRename: {
            jack_log("JackRequest::PortRename");
            JackPortRenameRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
            CheckWriteRefNum("JackRequest::PortRename", socket);
            break;
        }

        case JackRequest::kSetBufferSize: {
            jack_log("JackRequest::SetBufferSize");
            JackSetBufferSizeRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->SetBufferSize(req.fBufferSize);
            CheckWrite("JackRequest::SetBufferSize", socket);
            break;
        }

        case JackRequest::kSetFreeWheel: {
            jack_log("JackRequest::SetFreeWheel");
            JackSetFreeWheelRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->SetFreewheel(req.fOnOff);
            CheckWrite("JackRequest::SetFreeWheel", socket);
#ifdef __ANDROID__
#ifdef WORKAROUND_QC_JACK_ALSA
            /* for supporting qualcomm platform */
            if(req.fOnOff == 0) {
                usleep(300 * 1000);
                kill(getpid(), SIGUSR2);  //switch master driver via SIGUSR2 signal
                usleep(300 * 1000);
                kill(getpid(), SIGUSR2);  //switch master driver via SIGUSR2 signal
                usleep(300 * 1000);
                fServer->GetEngine()->PortConnect(0, "out:__system_playback_1", "system:playback_1");
                fServer->GetEngine()->PortConnect(0, "out:__system_playback_2", "system:playback_2");
                fServer->GetEngine()->PortConnect(0, "system:capture_1", "in:__system_capture_1");
                fServer->GetEngine()->PortConnect(0, "system:capture_2", "in:__system_capture_2");
            }
#endif
#endif
            break;
        }

         case JackRequest::kComputeTotalLatencies: {
            jack_log("JackRequest::ComputeTotalLatencies");
            JackComputeTotalLatenciesRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ComputeTotalLatencies();
            CheckWrite("JackRequest::ComputeTotalLatencies", socket);
            break;
        }

        case JackRequest::kReleaseTimebase: {
            jack_log("JackRequest::ReleaseTimebase");
            JackReleaseTimebaseRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->ReleaseTimebase(req.fRefNum);
            CheckWriteRefNum("JackRequest::ReleaseTimebase", socket);
            break;
        }

        case JackRequest::kSetTimebaseCallback: {
            jack_log("JackRequest::SetTimebaseCallback");
            JackSetTimebaseCallbackRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
            CheckWriteRefNum("JackRequest::SetTimebaseCallback", socket);
            break;
        }

        case JackRequest::kGetInternalClientName: {
            jack_log("JackRequest::GetInternalClientName");
            JackGetInternalClientNameRequest req;
            JackGetInternalClientNameResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
            CheckWriteRefNum("JackRequest::GetInternalClientName", socket);
            break;
        }

        case JackRequest::kInternalClientHandle: {
            jack_log("JackRequest::InternalClientHandle");
            JackInternalClientHandleRequest req;
            JackInternalClientHandleResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
            CheckWriteRefNum("JackRequest::InternalClientHandle", socket);
            break;
        }

        case JackRequest::kInternalClientLoad: {
            jack_log("JackRequest::InternalClientLoad");
            JackInternalClientLoadRequest req;
            JackInternalClientLoadResult res;
            CheckRead(req, socket);
            res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
            CheckWriteName("JackRequest::InternalClientLoad", socket);
            break;
        }

        case JackRequest::kInternalClientUnload: {
            jack_log("JackRequest::InternalClientUnload");
            JackInternalClientUnloadRequest req;
            JackInternalClientUnloadResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
            CheckWriteRefNum("JackRequest::InternalClientUnload", socket);
            break;
        }

        case JackRequest::kNotification: {
            jack_log("JackRequest::Notification");
            JackClientNotificationRequest req;
            CheckRead(req, socket);
            if (req.fNotify == kQUIT) {
                jack_log("JackRequest::Notification kQUIT");
                throw JackQuitException();
            } else {
                fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
            }
            break;
        }

        case JackRequest::kSessionNotify: {
            jack_log("JackRequest::SessionNotify");
            JackSessionNotifyRequest req;
            CheckRead(req, socket);
            fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL);
            break;
        }

        case JackRequest::kSessionReply: {
            jack_log("JackRequest::SessionReply");
            JackSessionReplyRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->SessionReply(req.fRefNum);
            CheckWrite("JackRequest::SessionReply", socket);
            break;
        }

        case JackRequest::kGetClientByUUID: {
            jack_log("JackRequest::GetClientByUUID");
            JackGetClientNameRequest req;
            JackClientNameResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName);
            CheckWrite("JackRequest::GetClientByUUID", socket);
            break;
        }

        case JackRequest::kGetUUIDByClient: {
            jack_log("JackRequest::GetUUIDByClient");
            JackGetUUIDRequest req;
            JackUUIDResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID);
            CheckWrite("JackRequest::GetUUIDByClient", socket);
            break;
        }

        case JackRequest::kReserveClientName: {
            jack_log("JackRequest::ReserveClientName");
            JackReserveNameRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID);
            CheckWrite("JackRequest::ReserveClientName", socket);
            break;
        }

        case JackRequest::kClientHasSessionCallback: {
            jack_log("JackRequest::ClientHasSessionCallback");
            JackClientHasSessionCallbackRequest req;
            JackResult res;
            CheckRead(req, socket);
            res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.fName);
            CheckWrite("JackRequest::ClientHasSessionCallback", socket);
            break;
        }

        default:
            jack_error("Unknown request %ld", type);
            return -1;
    }

    return 0;
}