xref: /haiku/src/kits/app/Messenger.cpp (revision d2e519391f2307e6e8b0d74df0c61021f8237473)
15edcfe96SAxel Dörfler /*
2d3206115SAxel Dörfler  * Copyright 2001-2015 Haiku, Inc. All rights reserved.
35edcfe96SAxel Dörfler  * Distributed under the terms of the MIT License.
45edcfe96SAxel Dörfler  *
55edcfe96SAxel Dörfler  * Authors:
65edcfe96SAxel Dörfler  *		Ingo Weinhold (bonefish@users.sf.net)
75edcfe96SAxel Dörfler  */
852a38012Sejakowatz 
952a38012Sejakowatz 
1052a38012Sejakowatz #include <Messenger.h>
1152a38012Sejakowatz 
125edcfe96SAxel Dörfler #include <new>
135edcfe96SAxel Dörfler #include <stdio.h>
143aeed660SJérôme Duval #include <strings.h>
1552a38012Sejakowatz 
16d3206115SAxel Dörfler #include <Application.h>
17d3206115SAxel Dörfler #include <AutoLocker.h>
18d3206115SAxel Dörfler #include <Handler.h>
19d3206115SAxel Dörfler #include <Looper.h>
20d3206115SAxel Dörfler #include <Message.h>
21d3206115SAxel Dörfler #include <OS.h>
22d3206115SAxel Dörfler #include <Roster.h>
23d3206115SAxel Dörfler 
24d3206115SAxel Dörfler #include <AppMisc.h>
25d3206115SAxel Dörfler #include <LaunchRoster.h>
26d3206115SAxel Dörfler #include <LooperList.h>
27d3206115SAxel Dörfler #include <MessagePrivate.h>
28d3206115SAxel Dörfler #include <MessageUtils.h>
29d3206115SAxel Dörfler #include <TokenSpace.h>
30d3206115SAxel Dörfler 
31cf10934eSMichael Lotz 
325edcfe96SAxel Dörfler // debugging
335edcfe96SAxel Dörfler //#define DBG(x) x
345edcfe96SAxel Dörfler #define DBG(x)
355edcfe96SAxel Dörfler #define OUT	printf
3652a38012Sejakowatz 
3752a38012Sejakowatz using BPrivate::gDefaultTokens;
3837faaadeSIngo Weinhold using BPrivate::gLooperList;
3937faaadeSIngo Weinhold using BPrivate::BLooperList;
4052a38012Sejakowatz 
4152a38012Sejakowatz 
BMessenger()4252a38012Sejakowatz BMessenger::BMessenger()
434ceb1e51SAxel Dörfler 	:
444ceb1e51SAxel Dörfler 	fPort(-1),
4594b98dffSIngo Weinhold 	fHandlerToken(B_NULL_TOKEN),
464ceb1e51SAxel Dörfler 	fTeam(-1)
4752a38012Sejakowatz {
4852a38012Sejakowatz }
4952a38012Sejakowatz 
504ceb1e51SAxel Dörfler 
BMessenger(const char * signature,team_id team,status_t * result)5152a38012Sejakowatz BMessenger::BMessenger(const char* signature, team_id team, status_t* result)
524ceb1e51SAxel Dörfler 	:
534ceb1e51SAxel Dörfler 	fPort(-1),
5494b98dffSIngo Weinhold 	fHandlerToken(B_NULL_TOKEN),
554ceb1e51SAxel Dörfler 	fTeam(-1)
5652a38012Sejakowatz {
574ceb1e51SAxel Dörfler 	_InitData(signature, team, result);
5852a38012Sejakowatz }
5952a38012Sejakowatz 
604ceb1e51SAxel Dörfler 
BMessenger(const BHandler * handler,const BLooper * looper,status_t * _result)6152a38012Sejakowatz BMessenger::BMessenger(const BHandler* handler, const BLooper* looper,
624ceb1e51SAxel Dörfler 	status_t* _result)
634ceb1e51SAxel Dörfler 	:
644ceb1e51SAxel Dörfler 	fPort(-1),
6594b98dffSIngo Weinhold 	fHandlerToken(B_NULL_TOKEN),
664ceb1e51SAxel Dörfler 	fTeam(-1)
6752a38012Sejakowatz {
686de47836SMichael Lotz 	_InitData(handler, looper, _result);
6952a38012Sejakowatz }
7052a38012Sejakowatz 
714ceb1e51SAxel Dörfler 
BMessenger(const BMessenger & other)726fd09955SJohn Scipione BMessenger::BMessenger(const BMessenger& other)
734ceb1e51SAxel Dörfler 	:
746fd09955SJohn Scipione 	fPort(other.fPort),
756fd09955SJohn Scipione 	fHandlerToken(other.fHandlerToken),
766fd09955SJohn Scipione 	fTeam(other.fTeam)
7752a38012Sejakowatz {
7852a38012Sejakowatz }
7952a38012Sejakowatz 
804ceb1e51SAxel Dörfler 
~BMessenger()8152a38012Sejakowatz BMessenger::~BMessenger()
8252a38012Sejakowatz {
8352a38012Sejakowatz }
8452a38012Sejakowatz 
8552a38012Sejakowatz 
864ceb1e51SAxel Dörfler //	#pragma mark - Target
8752a38012Sejakowatz 
884ceb1e51SAxel Dörfler 
8952a38012Sejakowatz bool
IsTargetLocal() const9052a38012Sejakowatz BMessenger::IsTargetLocal() const
9152a38012Sejakowatz {
924cad5abaSAxel Dörfler 	return BPrivate::current_team() == fTeam;
9352a38012Sejakowatz }
9452a38012Sejakowatz 
954ceb1e51SAxel Dörfler 
9652a38012Sejakowatz BHandler*
Target(BLooper ** _looper) const974ceb1e51SAxel Dörfler BMessenger::Target(BLooper** _looper) const
9852a38012Sejakowatz {
9952a38012Sejakowatz 	BHandler* handler = NULL;
10094f814b3SJérôme Duval 	if (IsTargetLocal()
10194f814b3SJérôme Duval 		&& (fHandlerToken > B_NULL_TOKEN
10294f814b3SJérôme Duval 			|| fHandlerToken == B_PREFERRED_TOKEN)) {
10352a38012Sejakowatz 		gDefaultTokens.GetToken(fHandlerToken, B_HANDLER_TOKEN,
10452a38012Sejakowatz 			(void**)&handler);
1054ceb1e51SAxel Dörfler 		if (_looper)
1064ceb1e51SAxel Dörfler 			*_looper = BPrivate::gLooperList.LooperForPort(fPort);
1074ceb1e51SAxel Dörfler 	} else if (_looper)
1084ceb1e51SAxel Dörfler 		*_looper = NULL;
1094ceb1e51SAxel Dörfler 
11052a38012Sejakowatz 	return handler;
11152a38012Sejakowatz }
11252a38012Sejakowatz 
1134ceb1e51SAxel Dörfler 
11452a38012Sejakowatz bool
LockTarget() const11552a38012Sejakowatz BMessenger::LockTarget() const
11652a38012Sejakowatz {
11752a38012Sejakowatz 	BLooper* looper = NULL;
11852a38012Sejakowatz 	Target(&looper);
119cd511790SAxel Dörfler 	if (looper != NULL && looper->Lock()) {
120930a139dSRene Gollent 		if (looper->fMsgPort == fPort)
121930a139dSRene Gollent 			return true;
122cd511790SAxel Dörfler 
123930a139dSRene Gollent 		looper->Unlock();
124930a139dSRene Gollent 		return false;
125930a139dSRene Gollent 	}
126930a139dSRene Gollent 
127930a139dSRene Gollent 	return false;
12852a38012Sejakowatz }
12952a38012Sejakowatz 
1304ceb1e51SAxel Dörfler 
13152a38012Sejakowatz status_t
LockTargetWithTimeout(bigtime_t timeout) const13252a38012Sejakowatz BMessenger::LockTargetWithTimeout(bigtime_t timeout) const
13352a38012Sejakowatz {
13452a38012Sejakowatz 	BLooper* looper = NULL;
13552a38012Sejakowatz 	Target(&looper);
136cd511790SAxel Dörfler 	if (looper == NULL)
137cd511790SAxel Dörfler 		return B_BAD_VALUE;
138cd511790SAxel Dörfler 
1396fd09955SJohn Scipione 	status_t result = looper->LockWithTimeout(timeout);
1404ceb1e51SAxel Dörfler 
1416fd09955SJohn Scipione 	if (result == B_OK && looper->fMsgPort != fPort) {
14287aa57e8SRene Gollent 		looper->Unlock();
143930a139dSRene Gollent 		return B_BAD_PORT_ID;
14487aa57e8SRene Gollent 	}
145930a139dSRene Gollent 
1466fd09955SJohn Scipione 	return result;
14752a38012Sejakowatz }
14852a38012Sejakowatz 
14952a38012Sejakowatz 
1504ceb1e51SAxel Dörfler //	#pragma mark - Message sending
15152a38012Sejakowatz 
152cd511790SAxel Dörfler 
15352a38012Sejakowatz status_t
SendMessage(uint32 command,BHandler * replyTo) const15452a38012Sejakowatz BMessenger::SendMessage(uint32 command, BHandler* replyTo) const
15552a38012Sejakowatz {
15652a38012Sejakowatz 	BMessage message(command);
15752a38012Sejakowatz 	return SendMessage(&message, replyTo);
15852a38012Sejakowatz }
15952a38012Sejakowatz 
160cd511790SAxel Dörfler 
16152a38012Sejakowatz status_t
SendMessage(BMessage * message,BHandler * replyTo,bigtime_t timeout) const16252a38012Sejakowatz BMessenger::SendMessage(BMessage* message, BHandler* replyTo,
16352a38012Sejakowatz 	bigtime_t timeout) const
16452a38012Sejakowatz {
16552a38012Sejakowatz 	DBG(OUT("BMessenger::SendMessage2(%.4s)\n", (char*)&message->what));
1666fd09955SJohn Scipione 
1676fd09955SJohn Scipione 	status_t result = message != NULL ? B_OK : B_BAD_VALUE;
1686fd09955SJohn Scipione 	if (result == B_OK) {
16952a38012Sejakowatz 		BMessenger replyMessenger(replyTo);
1706fd09955SJohn Scipione 		result = SendMessage(message, replyMessenger, timeout);
17152a38012Sejakowatz 	}
1726fd09955SJohn Scipione 
1736fd09955SJohn Scipione 	DBG(OUT("BMessenger::SendMessage2() done: %lx\n", result));
1746fd09955SJohn Scipione 
1756fd09955SJohn Scipione 	return result;
17652a38012Sejakowatz }
17752a38012Sejakowatz 
178cd511790SAxel Dörfler 
17952a38012Sejakowatz status_t
SendMessage(BMessage * message,BMessenger replyTo,bigtime_t timeout) const18052a38012Sejakowatz BMessenger::SendMessage(BMessage* message, BMessenger replyTo,
18152a38012Sejakowatz 	bigtime_t timeout) const
18252a38012Sejakowatz {
1836fd09955SJohn Scipione 	if (message == NULL)
1840d0f1600SJérôme Duval 		return B_BAD_VALUE;
1850d0f1600SJérôme Duval 
1869dbe170aSAxel Dörfler 	return BMessage::Private(message).SendMessage(fPort, fTeam, fHandlerToken,
1874ceb1e51SAxel Dörfler 		timeout, false, replyTo);
18852a38012Sejakowatz }
18952a38012Sejakowatz 
190cd511790SAxel Dörfler 
19152a38012Sejakowatz status_t
SendMessage(uint32 command,BMessage * reply) const19252a38012Sejakowatz BMessenger::SendMessage(uint32 command, BMessage* reply) const
19352a38012Sejakowatz {
19452a38012Sejakowatz 	BMessage message(command);
1956fd09955SJohn Scipione 
19652a38012Sejakowatz 	return SendMessage(&message, reply);
19752a38012Sejakowatz }
19852a38012Sejakowatz 
199cd511790SAxel Dörfler 
20052a38012Sejakowatz status_t
SendMessage(BMessage * message,BMessage * reply,bigtime_t deliveryTimeout,bigtime_t replyTimeout) const20152a38012Sejakowatz BMessenger::SendMessage(BMessage* message, BMessage* reply,
20252a38012Sejakowatz 	bigtime_t deliveryTimeout, bigtime_t replyTimeout) const
20352a38012Sejakowatz {
2048780db59SAxel Dörfler 	if (message == NULL || reply == NULL)
2058780db59SAxel Dörfler 		return B_BAD_VALUE;
2068780db59SAxel Dörfler 
2076fd09955SJohn Scipione 	status_t result = BMessage::Private(message).SendMessage(fPort, fTeam,
2084ceb1e51SAxel Dörfler 		fHandlerToken, reply, deliveryTimeout, replyTimeout);
209bdbd1cb4SMichael Lotz 
2106fd09955SJohn Scipione 	// map this result for now
2116fd09955SJohn Scipione 	if (result == B_BAD_TEAM_ID)
2126fd09955SJohn Scipione 		result = B_BAD_PORT_ID;
2138780db59SAxel Dörfler 
2146fd09955SJohn Scipione 	return result;
21552a38012Sejakowatz }
21652a38012Sejakowatz 
21752a38012Sejakowatz 
2184ceb1e51SAxel Dörfler //	#pragma mark - Operators and misc
21952a38012Sejakowatz 
2204ceb1e51SAxel Dörfler 
2216de47836SMichael Lotz status_t
SetTo(const char * signature,team_id team)2226de47836SMichael Lotz BMessenger::SetTo(const char* signature, team_id team)
2236de47836SMichael Lotz {
2246de47836SMichael Lotz 	status_t result = B_OK;
2256de47836SMichael Lotz 	_InitData(signature, team, &result);
2266fd09955SJohn Scipione 
2276de47836SMichael Lotz 	return result;
2286de47836SMichael Lotz }
2296de47836SMichael Lotz 
2306de47836SMichael Lotz 
2316de47836SMichael Lotz status_t
SetTo(const BHandler * handler,const BLooper * looper)2326de47836SMichael Lotz BMessenger::SetTo(const BHandler* handler, const BLooper* looper)
2336de47836SMichael Lotz {
2346de47836SMichael Lotz 	status_t result = B_OK;
2356de47836SMichael Lotz 	_InitData(handler, looper, &result);
2366fd09955SJohn Scipione 
2376de47836SMichael Lotz 	return result;
2386de47836SMichael Lotz }
2396de47836SMichael Lotz 
2406de47836SMichael Lotz 
24152a38012Sejakowatz BMessenger&
operator =(const BMessenger & other)2426fd09955SJohn Scipione BMessenger::operator=(const BMessenger& other)
24352a38012Sejakowatz {
2446fd09955SJohn Scipione 	if (this != &other) {
2456fd09955SJohn Scipione 		fPort = other.fPort;
2466fd09955SJohn Scipione 		fHandlerToken = other.fHandlerToken;
2476fd09955SJohn Scipione 		fTeam = other.fTeam;
24852a38012Sejakowatz 	}
2496fd09955SJohn Scipione 
2508f1dc17dSIngo Weinhold 	return *this;
25152a38012Sejakowatz }
25252a38012Sejakowatz 
2534ceb1e51SAxel Dörfler 
25452a38012Sejakowatz bool
operator ==(const BMessenger & other) const25552a38012Sejakowatz BMessenger::operator==(const BMessenger& other) const
25652a38012Sejakowatz {
2578f1dc17dSIngo Weinhold 	// Note: The fTeam fields are not compared.
2586fd09955SJohn Scipione 	return fPort == other.fPort && fHandlerToken == other.fHandlerToken;
25952a38012Sejakowatz }
26052a38012Sejakowatz 
2614ceb1e51SAxel Dörfler 
26252a38012Sejakowatz bool
IsValid() const26352a38012Sejakowatz BMessenger::IsValid() const
26452a38012Sejakowatz {
26552a38012Sejakowatz 	port_info info;
2664ceb1e51SAxel Dörfler 	return fPort >= 0 && get_port_info(fPort, &info) == B_OK;
26752a38012Sejakowatz }
26852a38012Sejakowatz 
2694ceb1e51SAxel Dörfler 
27052a38012Sejakowatz team_id
Team() const27152a38012Sejakowatz BMessenger::Team() const
27252a38012Sejakowatz {
27352a38012Sejakowatz 	return fTeam;
27452a38012Sejakowatz }
27552a38012Sejakowatz 
27652a38012Sejakowatz 
2773e8daeb7SIngo Weinhold uint32
HashValue() const2783e8daeb7SIngo Weinhold BMessenger::HashValue() const
2793e8daeb7SIngo Weinhold {
2803e8daeb7SIngo Weinhold 	return fPort * 19 + fHandlerToken;
2813e8daeb7SIngo Weinhold }
2823e8daeb7SIngo Weinhold 
2833e8daeb7SIngo Weinhold 
2844ceb1e51SAxel Dörfler //	#pragma mark - Private or reserved
28552a38012Sejakowatz 
2864ceb1e51SAxel Dörfler 
2876fd09955SJohn Scipione /*!	Sets the messenger's team, target looper port and handler token.
28852a38012Sejakowatz 
2896fd09955SJohn Scipione 	To target the preferred handler, use \c B_PREFERRED_TOKEN as token.
29052a38012Sejakowatz 
29152a38012Sejakowatz 	\param team The target's team.
29252a38012Sejakowatz 	\param port The target looper port.
29352a38012Sejakowatz 	\param token The target handler token.
29452a38012Sejakowatz */
2954afc60d3SIngo Weinhold void
_SetTo(team_id team,port_id port,int32 token)2964ceb1e51SAxel Dörfler BMessenger::_SetTo(team_id team, port_id port, int32 token)
29752a38012Sejakowatz {
29852a38012Sejakowatz 	fTeam = team;
29952a38012Sejakowatz 	fPort = port;
3004ceb1e51SAxel Dörfler 	fHandlerToken = token;
30152a38012Sejakowatz }
30252a38012Sejakowatz 
3034ceb1e51SAxel Dörfler 
3046fd09955SJohn Scipione /*!	Initializes the BMessenger object's data given the signature and/or
30552a38012Sejakowatz 	team ID of a target.
30652a38012Sejakowatz 
30752a38012Sejakowatz 	When only a signature is given, and multiple instances of the application
30852a38012Sejakowatz 	are running it is undeterminate which one is chosen as the target. In case
30952a38012Sejakowatz 	only a team ID is passed, the target application is identified uniquely.
31052a38012Sejakowatz 	If both are supplied, the application identified by the team ID must have
31152a38012Sejakowatz 	a matching signature, otherwise the initilization fails.
31252a38012Sejakowatz 
31352a38012Sejakowatz 	\param signature The target application's signature. May be \c NULL.
31452a38012Sejakowatz 	\param team The target application's team ID. May be < 0.
31552a38012Sejakowatz 	\param result An optional pointer to a pre-allocated status_t into which
31652a38012Sejakowatz 		   the result of the initialization is written.
31752a38012Sejakowatz */
31852a38012Sejakowatz void
_InitData(const char * signature,team_id team,status_t * _result)3194ceb1e51SAxel Dörfler BMessenger::_InitData(const char* signature, team_id team, status_t* _result)
32052a38012Sejakowatz {
3216fd09955SJohn Scipione 	status_t result = B_OK;
3226fd09955SJohn Scipione 
3239e9f5a1aSIngo Weinhold 	// get an app_info
3249e9f5a1aSIngo Weinhold 	app_info info;
3253b044715SIngo Weinhold 	if (team < 0) {
3269e9f5a1aSIngo Weinhold 		// no team ID given
3276fd09955SJohn Scipione 		if (signature != NULL) {
328d3206115SAxel Dörfler 			// Try existing launch communication data first
329d3206115SAxel Dörfler 			BMessage data;
330d3206115SAxel Dörfler 			if (BLaunchRoster().GetData(signature, data) == B_OK) {
331d3206115SAxel Dörfler 				info.port = data.GetInt32("port", -1);
332d3206115SAxel Dörfler 				team = data.GetInt32("team", -5);
333d3206115SAxel Dörfler 			}
334d3206115SAxel Dörfler 			if (info.port < 0) {
3356fd09955SJohn Scipione 				result = be_roster->GetAppInfo(signature, &info);
3369e9f5a1aSIngo Weinhold 				team = info.team;
337672c1ea9SIngo Weinhold 				// B_ERROR means that no application with the given signature
338672c1ea9SIngo Weinhold 				// is running. But we are supposed to return B_BAD_VALUE.
3396fd09955SJohn Scipione 				if (result == B_ERROR)
3406fd09955SJohn Scipione 					result = B_BAD_VALUE;
341672c1ea9SIngo Weinhold 			} else
342d3206115SAxel Dörfler 				info.flags = 0;
343d3206115SAxel Dörfler 		} else
3446fd09955SJohn Scipione 			result = B_BAD_TYPE;
3459e9f5a1aSIngo Weinhold 	} else {
3469e9f5a1aSIngo Weinhold 		// a team ID is given
3476fd09955SJohn Scipione 		result = be_roster->GetRunningAppInfo(team, &info);
3489e9f5a1aSIngo Weinhold 		// Compare the returned signature with the supplied one.
3496fd09955SJohn Scipione 		if (result == B_OK && signature != NULL
3506fd09955SJohn Scipione 			&& strcasecmp(signature, info.signature) != 0) {
3516fd09955SJohn Scipione 			result = B_MISMATCHED_VALUES;
3526fd09955SJohn Scipione 		}
3539e9f5a1aSIngo Weinhold 	}
3549e9f5a1aSIngo Weinhold 	// check whether the app flags say B_ARGV_ONLY
3556fd09955SJohn Scipione 	if (result == B_OK && (info.flags & B_ARGV_ONLY) != 0) {
3566fd09955SJohn Scipione 		result = B_BAD_TYPE;
357672c1ea9SIngo Weinhold 		// Set the team ID nevertheless -- that's what Be's implementation
358672c1ea9SIngo Weinhold 		// does. Don't know, if that is a bug, but at least it doesn't harm.
359672c1ea9SIngo Weinhold 		fTeam = team;
360672c1ea9SIngo Weinhold 	}
3613b044715SIngo Weinhold 	// init our members
3626fd09955SJohn Scipione 	if (result == B_OK) {
3633b044715SIngo Weinhold 		fTeam = team;
3643b044715SIngo Weinhold 		fPort = info.port;
36594b98dffSIngo Weinhold 		fHandlerToken = B_PREFERRED_TOKEN;
36652a38012Sejakowatz 	}
36752a38012Sejakowatz 
3686fd09955SJohn Scipione 	// return the result
3696fd09955SJohn Scipione 	if (_result != NULL)
3706fd09955SJohn Scipione 		*_result = result;
3714ceb1e51SAxel Dörfler }
3724ceb1e51SAxel Dörfler 
3734ceb1e51SAxel Dörfler 
3746fd09955SJohn Scipione /*!	Initializes the BMessenger to target the local BHandler and/or BLooper.
3756de47836SMichael Lotz 
3766de47836SMichael Lotz 	When a \c NULL handler is supplied, the preferred handler in the given
3776de47836SMichael Lotz 	looper is targeted. If no looper is supplied the looper the given handler
3786de47836SMichael Lotz 	belongs to is used -- that means in particular, that the handler must
3796de47836SMichael Lotz 	already belong to a looper. If both are supplied the handler must actually
3806de47836SMichael Lotz 	belong to looper.
3816de47836SMichael Lotz 
3826de47836SMichael Lotz 	\param handler The target handler. May be \c NULL.
3836de47836SMichael Lotz 	\param looper The target looper. May be \c NULL.
3846de47836SMichael Lotz 	\param result An optional pointer to a pre-allocated status_t into which
3856de47836SMichael Lotz 	       the result of the initialization is written.
3866de47836SMichael Lotz */
3876de47836SMichael Lotz void
_InitData(const BHandler * handler,const BLooper * looper,status_t * _result)3886de47836SMichael Lotz BMessenger::_InitData(const BHandler* handler, const BLooper* looper,
3896de47836SMichael Lotz 	status_t* _result)
3906de47836SMichael Lotz {
391*d2e51939SJérôme Duval 	status_t result = (handler != NULL || looper != NULL) ? B_OK : B_BAD_VALUE;
3926fd09955SJohn Scipione 	if (result == B_OK) {
3936fd09955SJohn Scipione 		if (handler != NULL) {
3946de47836SMichael Lotz 			// BHandler is given, check/retrieve the looper.
3956fd09955SJohn Scipione 			if (looper != NULL) {
3966de47836SMichael Lotz 				if (handler->Looper() != looper)
3976fd09955SJohn Scipione 					result = B_MISMATCHED_VALUES;
3986de47836SMichael Lotz 			} else {
3996de47836SMichael Lotz 				looper = handler->Looper();
4006de47836SMichael Lotz 				if (looper == NULL)
4016fd09955SJohn Scipione 					result = B_MISMATCHED_VALUES;
4026de47836SMichael Lotz 			}
4036de47836SMichael Lotz 		}
4046fd09955SJohn Scipione 
4056de47836SMichael Lotz 		// set port, token,...
4066fd09955SJohn Scipione 		if (result == B_OK) {
4076de47836SMichael Lotz 			AutoLocker<BLooperList> locker(gLooperList);
4086de47836SMichael Lotz 			if (locker.IsLocked() && gLooperList.IsLooperValid(looper)) {
4096de47836SMichael Lotz 				fPort = looper->fMsgPort;
4106fd09955SJohn Scipione 				fHandlerToken = handler != NULL
4116fd09955SJohn Scipione 					? _get_object_token_(handler)
4126fd09955SJohn Scipione 					: B_PREFERRED_TOKEN;
4136de47836SMichael Lotz 				fTeam = looper->Team();
4146de47836SMichael Lotz 			} else
4156fd09955SJohn Scipione 				result = B_BAD_VALUE;
4166de47836SMichael Lotz 		}
4176de47836SMichael Lotz 	}
4186fd09955SJohn Scipione 
4196fd09955SJohn Scipione 	if (_result != NULL)
4206fd09955SJohn Scipione 		*_result = result;
4216de47836SMichael Lotz }
4226de47836SMichael Lotz 
4236de47836SMichael Lotz 
424fd3c25a9SJohn Scipione //	#pragma mark - Operator functions
42552a38012Sejakowatz 
4268f1dc17dSIngo Weinhold 
42752a38012Sejakowatz bool
operator <(const BMessenger & _a,const BMessenger & _b)4284afc60d3SIngo Weinhold operator<(const BMessenger& _a, const BMessenger& _b)
42952a38012Sejakowatz {
4304afc60d3SIngo Weinhold 	BMessenger::Private a(const_cast<BMessenger&>(_a));
4314afc60d3SIngo Weinhold 	BMessenger::Private b(const_cast<BMessenger&>(_b));
4324afc60d3SIngo Weinhold 
4338f1dc17dSIngo Weinhold 	// significance:
4348f1dc17dSIngo Weinhold 	// 1. fPort
4358f1dc17dSIngo Weinhold 	// 2. fHandlerToken
4368f1dc17dSIngo Weinhold 	// 3. fPreferredTarget
4378f1dc17dSIngo Weinhold 	// fTeam is insignificant
4384afc60d3SIngo Weinhold 	return (a.Port() < b.Port()
4396eb09230SMichael Lotz 			|| (a.Port() == b.Port()
4404afc60d3SIngo Weinhold 				&& (a.Token() < b.Token()
4416eb09230SMichael Lotz 					|| (a.Token() == b.Token()
4424afc60d3SIngo Weinhold 						&& !a.IsPreferredTarget()
4436eb09230SMichael Lotz 						&& b.IsPreferredTarget()))));
44452a38012Sejakowatz }
44552a38012Sejakowatz 
4464ceb1e51SAxel Dörfler 
44752a38012Sejakowatz bool
operator !=(const BMessenger & a,const BMessenger & b)44852a38012Sejakowatz operator!=(const BMessenger& a, const BMessenger& b)
44952a38012Sejakowatz {
45052a38012Sejakowatz 	return !(a == b);
45152a38012Sejakowatz }
452