Skip to content
This repository was archived by the owner on Jul 8, 2022. It is now read-only.

Commit 91555df

Browse files
committed
Attempt to fix #455 and #456
Attempt to fix reconnection issues in Tango 9.3.0 and 9.3.1 when a client subscribes to several events (#455) Attempt to fix compatibility issues with Tango <= 8 device servers. This commit is based on @bourtemb's work on PR #465 and @Ingvord work done on PR #467 and PR #468. This solves merge conflicts between PR #467 and #468. Fix event field in EventData structure passed to user's callback (broken in Tango 9.3.0 and 9.3.1) Fix 1 unused variable compilation warning Add the possibility to compile the code on old compilers (issue with override keyword) Fix attribute name in EventData structure passed to user's callback for Attribute Config events
1 parent a3bc691 commit 91555df

File tree

5 files changed

+139
-102
lines changed

5 files changed

+139
-102
lines changed

cppapi/client/event.cpp

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,7 @@ int EventConsumer::connect_event(DeviceProxy *device,
13721372
int event_id)
13731373
{
13741374
int ret_event_id = event_id;
1375-
device_name = device->dev_name();
1375+
device_name = device->dev_name();//TODO convert to local
13761376
cout3 << "Tango::EventConsumer::connect_event(" << device_name << "," << obj_name <<"," << event << ")\n";
13771377

13781378
bool inter_event = false;
@@ -1580,7 +1580,7 @@ int EventConsumer::connect_event(DeviceProxy *device,
15801580
local_callback_key.insert(pos + 1,EVENT_COMPAT_IDL5);
15811581
}
15821582

1583-
initialize_received_from_admin(dvlsa, local_callback_key, adm_name, device->get_from_env_var());
1583+
ReceivedFromAdmin received_from_admin = initialize_received_from_admin(dvlsa, local_callback_key, adm_name, device->get_from_env_var());
15841584

15851585
//
15861586
// Do we already have this event in the callback map? If yes, simply add this new callback to the event callback list
@@ -1696,6 +1696,7 @@ int EventConsumer::connect_event(DeviceProxy *device,
16961696
EventCallBackStruct new_event_callback;
16971697
EventSubscribeStruct new_ess;
16981698

1699+
new_event_callback.received_from_admin = received_from_admin;
16991700
new_event_callback.device = device;
17001701
new_event_callback.obj_name = obj_name_lower;
17011702
new_event_callback.event_name = event_name;
@@ -1832,59 +1833,6 @@ string EventConsumer::get_client_attribute_name(const string &local_callback_key
18321833
return local_callback_key.substr(0, pos);
18331834
}
18341835

1835-
void Tango::EventConsumer::initialize_received_from_admin(const Tango::DevVarLongStringArray *dvlsa,
1836-
const string &local_callback_key,
1837-
const string &adm_name,
1838-
bool device_from_env_var)
1839-
{
1840-
if(dvlsa->lvalue.length() == 0)
1841-
{
1842-
EventSystemExcept::throw_exception(API_NotSupported,
1843-
"Server did not send its tango lib version. The server is possibly too old. The event system is not initialized!",
1844-
"EventConsumer::initialize_received_from_admin()");
1845-
}
1846-
1847-
long server_tango_lib_ver = dvlsa->lvalue[0];
1848-
1849-
//event name is used for zmq topics filtering
1850-
//channel name is used for heartbeat events
1851-
if (server_tango_lib_ver >= 930)
1852-
{
1853-
received_from_admin.event_name = (dvlsa->svalue[dvlsa->svalue.length() - 2]);
1854-
received_from_admin.channel_name = (dvlsa->svalue[dvlsa->svalue.length() - 1]);
1855-
}
1856-
else
1857-
{
1858-
received_from_admin.event_name = local_callback_key;
1859-
1860-
string adm_name_lower(adm_name);
1861-
if (device_from_env_var)
1862-
{
1863-
adm_name_lower.insert(0, env_var_fqdn_prefix[0]);
1864-
}
1865-
1866-
transform(adm_name_lower.begin(), adm_name_lower.end(), adm_name_lower.begin(), ::tolower);
1867-
received_from_admin.channel_name = adm_name_lower;
1868-
}
1869-
1870-
if (received_from_admin.event_name.empty())
1871-
{
1872-
EventSystemExcept::throw_exception(API_NotSupported,
1873-
"Server did not send the event name. The server is possibly too old. The event system is not initialized!",
1874-
"EventConsumer::initialize_received_from_admin()");
1875-
1876-
}
1877-
1878-
cout4 << "received_from_admin.event_name = " << received_from_admin.event_name << endl;
1879-
if (received_from_admin.channel_name.empty())
1880-
{
1881-
EventSystemExcept::throw_exception(API_NotSupported,
1882-
"Server did not send the channel name. The server is possibly too old. The event system is not initialized!",
1883-
"EventConsumer::initialize_received_from_admin()");
1884-
}
1885-
cout4 << "received_from_admin.channel_name = " << received_from_admin.channel_name << endl;
1886-
}
1887-
18881836
//+-------------------------------------------------------------------------------------------------------------------
18891837
//
18901838
// method :
@@ -3237,7 +3185,10 @@ void EventConsumer::get_fire_sync_event(DeviceProxy *device,CallBack *callback,E
32373185
err = e.errors;
32383186
}
32393187

3240-
string local_event_name = cb.get_client_attribute_name();
3188+
string local_event_name = event_name;
3189+
pos = local_event_name.find(EVENT_COMPAT);
3190+
if (pos != string::npos)
3191+
local_event_name.erase(0,EVENT_COMPAT_IDL5_SIZE);
32413192
string local_domain_name = cb.get_client_attribute_name();
32423193

32433194
if (cb.fwd_att == true)
@@ -3286,7 +3237,7 @@ void EventConsumer::get_fire_sync_event(DeviceProxy *device,CallBack *callback,E
32863237
{
32873238
DevErrorList err;
32883239
err.length(0);
3289-
string domain_name = device_name + "/" + obj_name_lower;
3240+
string local_domain_name = cb.get_client_attribute_name();
32903241
AttributeInfoEx *aie = NULL;
32913242

32923243
string local_event_name = event_name;
@@ -3305,7 +3256,7 @@ void EventConsumer::get_fire_sync_event(DeviceProxy *device,CallBack *callback,E
33053256
}
33063257

33073258
FwdAttrConfEventData *event_data = new FwdAttrConfEventData(device,
3308-
domain_name,
3259+
local_domain_name,
33093260
local_event_name,
33103261
aie,
33113262
err);

cppapi/client/eventconsumer.h

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,12 @@ typedef struct event_not_connected
329329

330330
//------------------------ Event Callback related info --------------------------------------
331331

332+
struct ReceivedFromAdmin
333+
{
334+
string event_name;
335+
string channel_name;
336+
};
337+
332338
typedef struct event_subscribe
333339
{
334340
EventQueue *ev_queue;
@@ -364,6 +370,7 @@ typedef struct event_callback: public EventCallBackBase, public EventCallBackZmq
364370
CosNotifyFilter::FilterID filter_id;
365371
bool filter_ok;
366372
string client_attribute_name;
373+
ReceivedFromAdmin received_from_admin;
367374
string get_client_attribute_name()
368375
{
369376
return client_attribute_name;
@@ -496,15 +503,12 @@ protected :
496503
virtual void set_channel_type(EventChannelStruct &) = 0;
497504
virtual void zmq_specific(DeviceData &,string &,DeviceProxy *,const string &) = 0;
498505

499-
void initialize_received_from_admin(const Tango::DevVarLongStringArray *pArray,
500-
const string &local_callback_key,
501-
const string &adm_name,
502-
bool device_from_env_var);
503-
struct
504-
{
505-
string event_name;
506-
string channel_name;
507-
} received_from_admin;
506+
507+
508+
virtual ReceivedFromAdmin initialize_received_from_admin(const Tango::DevVarLongStringArray *pArray,
509+
const string &local_callback_key,
510+
const string &adm_name,
511+
bool device_from_env_var)=0;
508512
};
509513

510514
/********************************************************************************
@@ -539,6 +543,17 @@ protected :
539543

540544
virtual void set_channel_type(EventChannelStruct &ecs) {ecs.channel_type = NOTIFD;}
541545
virtual void zmq_specific(DeviceData &,string &,DeviceProxy *,const string &) {}
546+
#ifdef HAS_OVERRIDE
547+
ReceivedFromAdmin initialize_received_from_admin(const Tango::DevVarLongStringArray *pArray,
548+
const string &local_callback_key,
549+
const string &adm_name,
550+
bool device_from_env_var) override;
551+
#else
552+
virtual ReceivedFromAdmin initialize_received_from_admin(const Tango::DevVarLongStringArray *pArray,
553+
const string &local_callback_key,
554+
const string &adm_name,
555+
bool device_from_env_var);
556+
#endif
542557

543558
private :
544559

@@ -598,6 +613,18 @@ protected :
598613
virtual void set_channel_type(EventChannelStruct &ecs) {ecs.channel_type = ZMQ;}
599614
virtual void zmq_specific(DeviceData &,string &,DeviceProxy *,const string &);
600615

616+
#ifdef HAS_OVERRIDE
617+
ReceivedFromAdmin initialize_received_from_admin(const Tango::DevVarLongStringArray *pArray,
618+
const string &local_callback_key,
619+
const string &adm_name,
620+
bool device_from_env_var) override;
621+
#else
622+
virtual ReceivedFromAdmin initialize_received_from_admin(const Tango::DevVarLongStringArray *pArray,
623+
const string &local_callback_key,
624+
const string &adm_name,
625+
bool device_from_env_var);
626+
#endif
627+
601628
private :
602629
TANGO_IMP static ZmqEventConsumer *_instance;
603630
zmq::context_t zmq_context; // ZMQ context

cppapi/client/notifdeventconsumer.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,5 +1139,26 @@ void NotifdEventConsumer::push_structured_event(const CosNotification::Structure
11391139
}
11401140
}
11411141

1142+
ReceivedFromAdmin NotifdEventConsumer::initialize_received_from_admin(TANGO_UNUSED(const Tango::DevVarLongStringArray *dvlsa),
1143+
const string &local_callback_key,
1144+
const string &adm_name,
1145+
bool device_from_env_var)
1146+
{
1147+
ReceivedFromAdmin result;
1148+
result.event_name = local_callback_key;
1149+
1150+
string full_adm_name(adm_name);
1151+
if (device_from_env_var)
1152+
{
1153+
full_adm_name.insert(0, env_var_fqdn_prefix[0]);
1154+
}
1155+
1156+
result.channel_name = full_adm_name;
1157+
1158+
cout4 << "received_from_admin.event_name = " << result.event_name << endl;
1159+
cout4 << "received_from_admin.channel_name = " << result.channel_name << endl;
1160+
return result;
1161+
}
1162+
11421163
} /* End of Tango namespace */
11431164

cppapi/client/zmqeventconsumer.cpp

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,41 +1658,11 @@ void ZmqEventConsumer::disconnect_event(string &event_name,string &endpoint)
16581658
//
16591659
//--------------------------------------------------------------------------------------------------------------------
16601660

1661-
void ZmqEventConsumer::connect_event_system(string &device_name,string &obj_name,string &event_name,TANGO_UNUSED(const vector<string> &filters),
1662-
TANGO_UNUSED(EvChanIte &eve_it),TANGO_UNUSED(EventCallBackStruct &new_event_callback),
1661+
void ZmqEventConsumer::connect_event_system(TANGO_UNUSED(string &device_name),TANGO_UNUSED(string &obj_name),
1662+
TANGO_UNUSED(string &event_name),TANGO_UNUSED(const vector<string> &filters),
1663+
TANGO_UNUSED(EvChanIte &eve_it),EventCallBackStruct &new_event_callback,
16631664
DeviceData &dd,size_t valid_end)
16641665
{
1665-
//
1666-
// Build full event name
1667-
// Don't forget case of device in a DS using file as database
1668-
//
1669-
1670-
string full_event_name;
1671-
string::size_type pos;
1672-
1673-
bool inter_event = false;
1674-
if (event_name == EventName[INTERFACE_CHANGE_EVENT])
1675-
inter_event = true;
1676-
1677-
if ((pos = device_name.find(MODIFIER_DBASE_NO)) != string::npos)
1678-
{
1679-
full_event_name = device_name;
1680-
if (inter_event == false)
1681-
{
1682-
string tmp = '/' + obj_name;
1683-
full_event_name.insert(pos,tmp);
1684-
}
1685-
full_event_name = full_event_name + '.' + event_name;
1686-
}
1687-
else
1688-
{
1689-
if (inter_event == true)
1690-
full_event_name = device_name + '.' + event_name;
1691-
else
1692-
full_event_name = device_name + '/' + obj_name + '.' + event_name;
1693-
}
1694-
1695-
16961666
//
16971667
// Extract server command result
16981668
//
@@ -1764,8 +1734,8 @@ void ZmqEventConsumer::connect_event_system(string &device_name,string &obj_name
17641734
::strcpy(&(buffer[length]),endpoint.c_str());
17651735
length = length + endpoint.size() + 1;
17661736

1767-
::strcpy(&(buffer[length]), received_from_admin.event_name.c_str());
1768-
length = length + received_from_admin.event_name.size() + 1;
1737+
::strcpy(&(buffer[length]), new_event_callback.received_from_admin.event_name.c_str());
1738+
length = length + new_event_callback.received_from_admin.event_name.size() + 1;
17691739

17701740
DevLong user_hwm = au->get_user_sub_hwm();
17711741
if (user_hwm != -1)
@@ -3513,6 +3483,69 @@ void ZmqEventConsumer::set_socket_hwm(int hwm)
35133483
}
35143484
}
35153485

3486+
ReceivedFromAdmin ZmqEventConsumer::initialize_received_from_admin(const Tango::DevVarLongStringArray *dvlsa,
3487+
const string &local_callback_key,
3488+
const string &adm_name,
3489+
bool device_from_env_var)
3490+
{
3491+
ReceivedFromAdmin result;
3492+
if (dvlsa->lvalue.length() == 0)
3493+
{
3494+
EventSystemExcept::throw_exception(API_NotSupported,
3495+
"Server did not send its tango lib version. The server is possibly too old. The event system is not initialized!",
3496+
"ZmqEventConsumer::initialize_received_from_admin()");
3497+
}
3498+
3499+
long server_tango_lib_ver = dvlsa->lvalue[0];
3500+
3501+
//event name is used for zmq topics filtering
3502+
//channel name is used for heartbeat events
3503+
if (server_tango_lib_ver >= 930)
3504+
{
3505+
result.event_name = (dvlsa->svalue[dvlsa->svalue.length() - 2]);
3506+
result.channel_name = (dvlsa->svalue[dvlsa->svalue.length() - 1]);
3507+
}
3508+
else
3509+
{
3510+
result.event_name = local_callback_key;
3511+
3512+
if(server_tango_lib_ver >= 810)
3513+
{
3514+
string adm_name_lower(adm_name);
3515+
if (device_from_env_var)
3516+
{
3517+
adm_name_lower.insert(0, env_var_fqdn_prefix[0]);
3518+
}
3519+
transform(adm_name_lower.begin(), adm_name_lower.end(), adm_name_lower.begin(), ::tolower);
3520+
result.channel_name = adm_name_lower;
3521+
}
3522+
else
3523+
{
3524+
// For event coming from server still using Tango 8.0.x or below, do not lowercase
3525+
// the adm_name in the channel name
3526+
result.channel_name = adm_name;
3527+
}
3528+
}
3529+
3530+
if (result.event_name.empty())
3531+
{
3532+
EventSystemExcept::throw_exception(API_NotSupported,
3533+
"Server did not send the event name. The server is possibly too old. The event system is not initialized!",
3534+
"ZmqEventConsumer::initialize_received_from_admin()");
3535+
3536+
}
3537+
3538+
cout4 << "received_from_admin.event_name = " << result.event_name << endl;
3539+
if (result.channel_name.empty())
3540+
{
3541+
EventSystemExcept::throw_exception(API_NotSupported,
3542+
"Server did not send the channel name. The server is possibly too old. The event system is not initialized!",
3543+
"ZmqEventConsumer::initialize_received_from_admin()");
3544+
}
3545+
cout4 << "received_from_admin.channel_name = " << result.channel_name << endl;
3546+
return result;
3547+
}
3548+
35163549
//--------------------------------------------------------------------------------------------------------------------
35173550
//
35183551
// method :

cppapi/server/tango_config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@
163163
#define HAS_RANGE_BASE_FOR
164164
#define INIT_LIST
165165
#endif
166+
#if __GNUC_MINOR__ > 6
167+
#define HAS_OVERRIDE
168+
#endif
166169
#if __GNUC_MINOR__ > 7
167170
#define HAS_UNDERLYING
168171
#define HAS_ATTRIBUTE_SPECIFIERS
@@ -229,6 +232,7 @@
229232
#define HAS_UNDERLYING
230233
#define HAS_VARIADIC_TEMPLATE
231234
#define HAS_MAP_AT
235+
#define HAS_OVERRIDE
232236
#endif
233237
#ifdef WIN32_VC14
234238
#define HAS_UNIQUE_PTR
@@ -241,6 +245,7 @@
241245
#define HAS_VARIADIC_TEMPLATE
242246
#define HAS_MAP_AT
243247
#define HAS_ATTRIBUTE_SPECIFIERS
248+
#define HAS_OVERRIDE
244249
#endif
245250
#endif
246251

0 commit comments

Comments
 (0)