summaryrefslogtreecommitdiff
path: root/tubes
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-03-30 18:43:22 +0100
committerMatúš Kukan <matus.kukan@gmail.com>2012-07-17 16:40:06 +0200
commit86268ec22035855de9a505706c35217ba5a11565 (patch)
tree2a34667db715574846ea291e259d85abd8db32d7 /tubes
parent226149126eae9911b5e7dc71567a8889051553d7 (diff)
tubes: move Accept() logic into conference
This makes sense, because the flow for Accept() and Offer() is basically symmetrical, and then conference becomes solely responsible for the handling of channels once they've been requested/given to us. While we're at it we also fix both code paths to work correctly if the state becomes Open before Accept/Offer returns (which is possible).
Diffstat (limited to 'tubes')
-rw-r--r--tubes/inc/tubes/conference.hxx15
-rw-r--r--tubes/inc/tubes/manager.hxx12
-rw-r--r--tubes/source/conference.cxx124
-rw-r--r--tubes/source/manager.cxx66
4 files changed, 98 insertions, 119 deletions
diff --git a/tubes/inc/tubes/conference.hxx b/tubes/inc/tubes/conference.hxx
index f4ae973a7737..4ae49c84530f 100644
--- a/tubes/inc/tubes/conference.hxx
+++ b/tubes/inc/tubes/conference.hxx
@@ -82,36 +82,39 @@ public:
void setChannel( TpAccount* pAccount, TpChannel* pChannel );
TpChannel* getChannel() const { return mpChannel; }
bool offerTube();
- bool acceptTube( const char* pAddress );
+ bool acceptTube();
/// got tube accepted on other end as well?
bool isTubeOpen() const { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; }
// Only for callbacks.
void setTubeOfferedHandlerInvoked( bool b ) { mbTubeOfferedHandlerInvoked = b; }
bool isTubeOfferedHandlerInvoked() const { return mbTubeOfferedHandlerInvoked; }
- void setTubeChannelStateChangedHandlerInvoked( bool b )
- { mbTubeChannelStateChangedHandlerInvoked = b; }
- bool isTubeChannelStateChangedHandlerInvoked() const
- { return mbTubeChannelStateChangedHandlerInvoked; }
+ bool isTubeChannelStateChangedToOpen() const
+ { return meTubeChannelState == TP_TUBE_CHANNEL_STATE_OPEN; };
void setTubeChannelState( TpTubeChannelState eState ) { meTubeChannelState = eState; }
+ static void TubeChannelStateChangedHandler(TpChannel*, guint, void*, GObject*);
static void TubeOfferedHandler(TpChannel* pChannel, const gchar* pAddress, const GError* pError,
gpointer pUserData, GObject*pWeakObject);
+ static void TubeAcceptedHandler(TpChannel* pChannel, const gchar* pAddress, const GError* pError,
+ gpointer pUserData, GObject*pWeakObject);
static void FTReady( EmpathyFTHandler *handler, GError *error, gpointer user_data);
private:
+ bool tryToOpen();
+ bool spinUntilTubeEstablished();
bool setTube( const char* pTube );
rtl::OString maSessionId;
TeleManager* mpManager;
TpAccount* mpAccount;
TpChannel* mpChannel;
+ gchar* mpAddress;
DBusConnection* mpTube;
TelePacketQueue maPacketQueue;
TpTubeChannelState meTubeChannelState;
bool mbTubeOfferedHandlerInvoked : 1;
- bool mbTubeChannelStateChangedHandlerInvoked : 1;
// hide from the public
using boost::enable_shared_from_this<TeleConference>::shared_from_this;
diff --git a/tubes/inc/tubes/manager.hxx b/tubes/inc/tubes/manager.hxx
index 74d04246aea3..75e298c1c60e 100644
--- a/tubes/inc/tubes/manager.hxx
+++ b/tubes/inc/tubes/manager.hxx
@@ -131,8 +131,6 @@ public:
void disconnect();
- void acceptTube( TpAccount* pAccount, TpChannel* pChannel, const char* pAddress );
-
/** Send data to all registered conferences.
@returns to how many conferences the packet was send
@@ -217,6 +215,16 @@ public:
/* Callbacks; not for use outside this class. */
static void TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer user_data);
+ static void DBusChannelHandler(
+ TpSimpleHandler* /*handler*/,
+ TpAccount* pAccount,
+ TpConnection* /*connection*/,
+ GList* pChannels,
+ GList* /*requests_satisfied*/,
+ gint64 /*user_action_time*/,
+ TpHandleChannelsContext* pContext,
+ gpointer pUserData);
+
private:
void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy );
diff --git a/tubes/source/conference.cxx b/tubes/source/conference.cxx
index 82eb1e78af14..824b9c828056 100644
--- a/tubes/source/conference.cxx
+++ b/tubes/source/conference.cxx
@@ -169,34 +169,48 @@ void TeleConference::TubeOfferedHandler(
if (pChannel != pConference->getChannel())
return;
- pConference->setTube( pAddress );
+ pConference->mpAddress = g_strdup( pAddress );
+ pConference->tryToOpen();
}
-static void TeleConference_TubeChannelStateChangedHandler(
+bool TeleConference::tryToOpen()
+{
+ if (mpTube)
+ return true;
+
+ if (!isTubeOpen())
+ return false;
+
+ if (!mpAddress)
+ return false;
+
+ return setTube( mpAddress);
+}
+
+void TeleConference::TubeChannelStateChangedHandler(
TpChannel* pChannel,
guint nState,
gpointer pUserData,
GObject* /*weak_object*/
)
{
- INFO_LOGGER_F( "TeleConference_TubeChannelStateChangedHandler");
+ INFO_LOGGER_F( "TeleConference::TubeChannelStateChangedHandler");
- SAL_INFO( "tubes", "TeleConference_TubeChannelStateChangedHandler: state: " << static_cast<sal_uInt32>(nState));
+ SAL_INFO( "tubes", "TeleConference::TubeChannelStateChangedHandler: state: " << static_cast<sal_uInt32>(nState));
TeleConference* pConference = reinterpret_cast<TeleConference*>(pUserData);
SAL_WARN_IF( !pConference, "tubes", "TeleConference_DBusMessageHandler: no conference");
if (!pConference)
return;
- pConference->setTubeChannelStateChangedHandlerInvoked( true);
-
SAL_WARN_IF( pChannel != pConference->getChannel(), "tubes",
- "TeleConference_TubeChannelStateChangedHandler: not my channel");
+ "TeleConference::TubeChannelStateChangedHandler: not my channel");
if (pChannel != pConference->getChannel())
return;
pConference->setTubeChannelState( static_cast<TpTubeChannelState>(nState));
+ pConference->tryToOpen();
}
@@ -204,18 +218,14 @@ TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpCh
:
maSessionId( rSessionId ),
mpManager( pManager),
- mpAccount( pAccount),
- mpChannel( pChannel),
+ mpAccount( NULL),
+ mpChannel( NULL),
+ mpAddress( NULL),
mpTube( NULL),
meTubeChannelState( TP_TUBE_CHANNEL_STATE_NOT_OFFERED),
- mbTubeOfferedHandlerInvoked( false),
- mbTubeChannelStateChangedHandlerInvoked( false)
+ mbTubeOfferedHandlerInvoked( false)
{
- if (mpAccount)
- g_object_ref( mpAccount);
-
- if (mpChannel)
- g_object_ref( mpChannel);
+ setChannel( pAccount, pChannel );
}
@@ -234,30 +244,59 @@ void TeleConference::setChannel( TpAccount *pAccount, TpChannel* pChannel )
g_object_unref( mpAccount);
mpChannel = pChannel;
- if (mpChannel)
+ if (mpChannel) {
g_object_ref( mpChannel);
+ /* TODO: remember the TpProxySignalConnection and disconnect in finalize */
+ GError* pError = NULL;
+ TpProxySignalConnection* pProxySignalConnection =
+ tp_cli_channel_interface_tube_connect_to_tube_channel_state_changed(
+ mpChannel,
+ &TeleConference::TubeChannelStateChangedHandler,
+ this,
+ NULL,
+ NULL,
+ &pError);
+
+ if (!pProxySignalConnection || pError)
+ {
+ SAL_WARN_IF( pError, "tubes",
+ "TeleConference::setChannel: channel state changed error: " << pError->message);
+ g_error_free( pError);
+ }
+ }
+
mpAccount = pAccount;
if (mpAccount)
g_object_ref( mpAccount);
}
-bool TeleConference::acceptTube( const char* pAddress )
+bool TeleConference::spinUntilTubeEstablished()
{
- INFO_LOGGER( "TeleConference::acceptTube");
+ mpManager->iterateLoop( this, &TeleConference::isTubeOfferedHandlerInvoked);
+ mpManager->iterateLoop( this, &TeleConference::isTubeChannelStateChangedToOpen);
- SAL_WARN_IF( !pAddress, "tubes", "TeleConference::acceptTube: no address");
- if (!pAddress)
- return false;
- SAL_INFO( "tubes", "TeleConference::acceptTube: address: " << pAddress);
+ bool bOpen = isTubeOpen();
+ SAL_INFO( "tubes", "TeleConference::spinUntilTubeEstablished: tube open: " << bOpen);
+ return bOpen;
+}
+
+
+bool TeleConference::acceptTube()
+{
+ INFO_LOGGER( "TeleConference::acceptTube");
SAL_WARN_IF( !mpChannel, "tubes", "TeleConference::acceptTube: no channel setup");
SAL_WARN_IF( mpTube, "tubes", "TeleConference::acceptTube: already tubed");
if (!mpChannel || mpTube)
return false;
- return setTube( pAddress );
+ tp_cli_channel_type_dbus_tube_call_accept( mpChannel, -1,
+ TP_SOCKET_ACCESS_CONTROL_CREDENTIALS,
+ &TeleConference::TubeOfferedHandler,
+ this, NULL, NULL);
+ return spinUntilTubeEstablished();
}
@@ -269,8 +308,6 @@ bool TeleConference::offerTube()
if (!mpChannel)
return false;
- setTubeOfferedHandlerInvoked( false);
-
// We must pass a hash table, it could be empty though.
/* TODO: anything meaningful to go in here? */
GHashTable* pParams = tp_asv_new(
@@ -287,35 +324,8 @@ bool TeleConference::offerTube()
NULL, // destroy
NULL); // weak_object
- mpManager->iterateLoop( this, &TeleConference::isTubeOfferedHandlerInvoked);
-
g_hash_table_unref( pParams);
-
- setTubeChannelStateChangedHandlerInvoked( false);
-
- /* TODO: remember the TpProxySignalConnection for further use? */
- GError* pError = NULL;
- TpProxySignalConnection* pProxySignalConnection =
- tp_cli_channel_interface_tube_connect_to_tube_channel_state_changed(
- mpChannel,
- TeleConference_TubeChannelStateChangedHandler,
- this,
- NULL,
- NULL,
- &pError);
-
- if (!pProxySignalConnection || pError)
- {
- SAL_WARN_IF( pError, "tubes", "TeleConference::offerTube: channel state changed error: " << pError->message);
- g_error_free( pError);
- return false;
- }
-
- mpManager->iterateLoop( this, &TeleConference::isTubeChannelStateChangedHandlerInvoked);
-
- bool bOpen = isTubeOpen();
- SAL_INFO( "tubes", "TeleConference::offerTube: tube open: " << bOpen);
- return bOpen;
+ return spinUntilTubeEstablished();
}
@@ -379,6 +389,12 @@ void TeleConference::finalize()
mpTube = NULL;
}
+ if (mpAddress)
+ {
+ g_free( mpAddress);
+ mpAddress = NULL;
+ }
+
TeleConferencePtr pThis( shared_from_this());
mpManager->unregisterConference( pThis);
diff --git a/tubes/source/manager.cxx b/tubes/source/manager.cxx
index b9ecfd0a00c8..32589f10a9ae 100644
--- a/tubes/source/manager.cxx
+++ b/tubes/source/manager.cxx
@@ -92,38 +92,7 @@ public:
};
-static void TeleManager_DBusTubeAcceptHandler(
- TpChannel* pChannel,
- const char* pAddress,
- const GError* pError,
- gpointer pUserData,
- GObject* pWeakObject)
-{
- INFO_LOGGER_F( "TeleManager_DBusTubeAcceptHandler");
-
- TpAccount* pAccount = TP_ACCOUNT(pWeakObject);
-
- SAL_WARN_IF( pError, "tubes", "TeleManager_DBusTubeAcceptHandler: entered with error: " << pError->message);
- if (pError)
- {
- g_object_unref(pAccount);
- return;
- }
-
- TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
- SAL_WARN_IF( !pManager, "tubes", "TeleManager_DBusTubeAcceptHandler: no manager");
- if (!pManager)
- {
- g_object_unref(pAccount);
- return;
- }
-
- pManager->acceptTube( pAccount, pChannel, pAddress);
- g_object_unref (pAccount);
-}
-
-
-static void TeleManager_DBusChannelHandler(
+void TeleManager::DBusChannelHandler(
TpSimpleHandler* /*handler*/,
TpAccount* pAccount,
TpConnection* /*connection*/,
@@ -134,10 +103,10 @@ static void TeleManager_DBusChannelHandler(
gpointer pUserData)
{
bool aAccepted = false;
- INFO_LOGGER_F( "TeleManager_DBusChannelHandler");
+ INFO_LOGGER_F( "TeleManager::DBusChannelHandler");
TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
- SAL_WARN_IF( !pManager, "tubes", "TeleManager_DBusChannelHandler: no manager");
+ SAL_WARN_IF( !pManager, "tubes", "TeleManager::DBusChannelHandler: no manager");
if (!pManager)
return;
@@ -147,18 +116,17 @@ static void TeleManager_DBusChannelHandler(
if (!pChannel)
continue;
- SAL_INFO( "tubes", "TeleManager_DBusChannelHandler: incoming dbus channel: "
+ SAL_INFO( "tubes", "TeleManager::DBusChannelHandler: incoming dbus channel: "
<< tp_channel_get_identifier( pChannel));
if (tp_channel_get_channel_type_id( pChannel) == TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE)
{
SAL_INFO( "tubes", "accepting");
aAccepted = true;
- g_object_ref( pAccount);
- tp_cli_channel_type_dbus_tube_call_accept( pChannel, -1,
- TP_SOCKET_ACCESS_CONTROL_CREDENTIALS,
- TeleManager_DBusTubeAcceptHandler, pUserData, NULL,
- G_OBJECT (pAccount));
+
+ TeleConferencePtr pConference( new TeleConference( pManager, pAccount, pChannel, ""));
+ pManager->maConferences.push_back( pConference);
+ pConference->acceptTube();
}
else
{
@@ -456,7 +424,7 @@ bool TeleManager::connect()
FALSE, // requests
getFullClientName().getStr(), // name
FALSE, // uniquify
- TeleManager_DBusChannelHandler, // callback
+ &TeleManager::DBusChannelHandler, // callback
this, // user_data
NULL // destroy
);
@@ -847,22 +815,6 @@ void TeleManager::disconnect()
}
-void TeleManager::acceptTube( TpAccount* pAccount, TpChannel* pChannel, const char* pAddress )
-{
- INFO_LOGGER( "TeleManager::acceptTube");
-
- SAL_INFO( "tubes", "TeleManager::acceptTube: address " << pAddress);
-
- SAL_WARN_IF( !pChannel || !pAddress, "tubes", "TeleManager::acceptTube: no channel or no address");
- if (!pChannel || !pAddress)
- return;
-
- TeleConferencePtr pConference( new TeleConference( this, pAccount, pChannel, ""));
- maConferences.push_back( pConference);
- pConference->acceptTube( pAddress);
-}
-
-
void TeleManager::setAccountManagerReady( bool bPrepared)
{
pImpl->meAccountManagerStatus = (bPrepared ? AMS_PREPARED : AMS_UNPREPARABLE);