From e31148095d0467de1c10d794b54c1289d92356a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 15 Apr 2015 17:46:38 +0200 Subject: [PATCH] BMessage: fixed reply port race condition. * When the team that we got the synchronous reply from immediately terminated afterwards, it might have still owned (and therefore destroyed) our reply port. * Make sure it's not added to the pool again, but is recreated instead. --- src/kits/app/Message.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index e9a3a987c9..aa7729cff7 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2014 Haiku, Inc. All rights reserved. + * Copyright 2005-2015 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -58,7 +58,7 @@ #if BMESSAGE_TRACING # define KTRACE(format...) ktrace_printf(format) #else -# define KTRACE(format...) +# define KTRACE(format...) ; #endif @@ -2276,6 +2276,8 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token, replyPort = sReplyPorts[cachedReplyPort]; } + bool recreateCachedPort = false; + team_id team = B_BAD_TEAM_ID; if (be_app != NULL) team = be_app->Team(); @@ -2345,15 +2347,18 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token, result = handle_reply(replyPort, &code, replyTimeout, reply); if (result != B_OK && cachedReplyPort >= 0) { delete_port(replyPort); - sReplyPorts[cachedReplyPort] = create_port(1, "tmp_rport"); + recreateCachedPort = true; } error: if (cachedReplyPort >= 0) { - // Reclaim ownership of cached port - set_port_owner(replyPort, team); - // Flag as available - atomic_add(&sReplyPortInUse[cachedReplyPort], -1); + // Reclaim ownership of cached port, if possible + if (!recreateCachedPort && set_port_owner(replyPort, team) == B_OK) { + // Flag as available + atomic_add(&sReplyPortInUse[cachedReplyPort], -1); + } else + sReplyPorts[cachedReplyPort] = create_port(1, "tmp_rport"); + return result; }