mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	HLE/SRV: Don't return the port handle if it isn't available when calling GetServiceHandle.
This was incorrect behavior that somehow found its way to 3dbrew. The correct behavior is to sleep until the port becomes available again and then return a session to it. This is currently unimplemented due to the inability to put a guest thread to sleep during HLE requests. The correct behavior was reverse engineered by TuxSH a while ago but we never corrected the code in citra.
This commit is contained in:
		
							parent
							
								
									d55a13c35d
								
							
						
					
					
						commit
						afb6dd7747
					
				
					 1 changed files with 5 additions and 7 deletions
				
			
		|  | @ -87,7 +87,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { | ||||||
|     size_t name_len = rp.Pop<u32>(); |     size_t name_len = rp.Pop<u32>(); | ||||||
|     u32 flags = rp.Pop<u32>(); |     u32 flags = rp.Pop<u32>(); | ||||||
| 
 | 
 | ||||||
|     bool return_port_on_failure = (flags & 1) == 0; |     bool wait_until_available = (flags & 1) == 0; | ||||||
| 
 | 
 | ||||||
|     if (name_len > Service::kMaxPortSize) { |     if (name_len > Service::kMaxPortSize) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|  | @ -115,12 +115,10 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|         rb.Push(session.Code()); |         rb.Push(session.Code()); | ||||||
|         rb.PushObjects(std::move(session).Unwrap()); |         rb.PushObjects(std::move(session).Unwrap()); | ||||||
|     } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && return_port_on_failure) { |     } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && wait_until_available) { | ||||||
|         LOG_WARNING(Service_SRV, "called service=%s -> ERR_MAX_CONNECTIONS_REACHED, *port*=%u", |         LOG_WARNING(Service_SRV, "called service=%s -> ERR_MAX_CONNECTIONS_REACHED", name.c_str()); | ||||||
|                     name.c_str(), (*client_port)->GetObjectId()); |         // TODO(Subv): Put the caller guest thread to sleep until this port becomes available again.
 | ||||||
|         IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |         UNIMPLEMENTED_MSG("Unimplemented wait until port %s is available.", name.c_str()); | ||||||
|         rb.Push(ERR_MAX_CONNECTIONS_REACHED); |  | ||||||
|         rb.PushObjects(std::move(client_port).Unwrap()); |  | ||||||
|     } else { |     } else { | ||||||
|         LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), |         LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), | ||||||
|                   session.Code().raw); |                   session.Code().raw); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue