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