diff --git a/source/os.cpp b/source/os.cpp index 958ed17..fef2c9c 100644 --- a/source/os.cpp +++ b/source/os.cpp @@ -1101,16 +1101,12 @@ void ObserverSubject::Unregister(std::shared_ptr thread) { // TODOTEST: What happens if the application were doing something stupid like // SVCWaitSynchronizationN'ing on multiple server port handles with the -// wait_for_all flag set to true? In our implementation, incoming_session -// would be overwritten and hence the first server port acquisition being -// silently dropped! +// wait_for_all flag set to true? bool ServerPort::TryAcquireImpl(std::shared_ptr thread) { - if (session_queue.empty()) - return false; - - thread->incoming_session = session_queue.front(); - session_queue.pop(); - return true; + // NOTE: Some modules call SVCWaitSynchronization again after waking up + // on a ServerPort handle in SVCReplyAndReceive. Hence, acquisition + // must be idempotent. + return !session_queue.empty(); } void ServerPort::OfferSession(std::shared_ptr session) { @@ -3304,11 +3300,12 @@ SVCFuture,HandleTable::Entry> OS::SVCAcceptSession(Thread& source, ServerPort& server_port) { source.GetLogger()->info("{}SVCAcceptSession: server_port={}", ThreadPrinter{source}, ObjectRefPrinter{server_port}); - if (!source.incoming_session) { + if (server_port.session_queue.empty()) { throw Mikage::Exceptions::Invalid("Attempted to accept nonexisting session"); } + auto session = server_port.session_queue.front(); + server_port.session_queue.pop(); - std::shared_ptr session = std::move(source.incoming_session); source.GetLogger()->info("{}SVCAcceptSession: accepting session {} / {}", ThreadPrinter{source}, ObjectPrinter{session}, ObjectPrinter{session->client.lock()}); diff --git a/source/os.hpp b/source/os.hpp index 0266217..870c41a 100644 --- a/source/os.hpp +++ b/source/os.hpp @@ -363,8 +363,6 @@ public: */ std::weak_ptr woken_object; - std::shared_ptr incoming_session; - // Notify thread of a resource being ready for being TryAcquire'ed // TODO: This function is unused now! void SignalResourceReady();