@@ -160,15 +160,14 @@ static core_object_t **core_object_list(const core_object_klass_t klass,
160160/* Object callbacks */
161161static void core_object_command_complete (uint64_t command_id , int64_t result ,
162162 void * , void * data );
163- static int core_object_event_register (const core_object_klass_t klass ,
164- const core_object_event_type_t event ,
165- const char * name , core_object_t * object ,
166- event_handler_t handler , void * user_data );
167- static int core_object_event_unregister (const core_object_klass_t klass ,
168- const core_object_event_type_t event ,
169- const char * name , core_object_t * object ,
170- event_handler_t handler ,
171- void * user_data );
163+ static core_event_token_t core_object_event_register (const core_object_klass_t klass ,
164+ const core_object_event_type_t event ,
165+ const char * name ,
166+ core_object_t * object ,
167+ event_handler_t handler ,
168+ void * user_data );
169+
170+ static int core_object_event_unregister (const core_event_token_t token , void * user_data );
172171static int core_object_event_submit (const core_object_event_type_t event ,
173172 const core_object_id_t id , void * event_data ,
174173 void * user_data );
@@ -265,8 +264,8 @@ static void core_process_events(void *arg) {
265264 event -> data );
266265 else {
267266 PyGILState_STATE state = PyGILState_Ensure ();
268- PyObject * args = Py_BuildValue ("(isik )" , object -> klass ,
269- object -> name , event -> type ,
267+ PyObject * args = Py_BuildValue ("(kisik )" , ( core_event_token_t ) subscription ,
268+ object -> klass , object -> name , event -> type ,
270269 event -> data );
271270 if (!args ) {
272271 PyErr_Print ();
@@ -1149,10 +1148,12 @@ static PyObject *vortex_core_get_status(PyObject *self, PyObject *args) {
11491148 return NULL ;
11501149}
11511150
1152- static int core_object_event_register (const core_object_klass_t klass ,
1153- const core_object_event_type_t event ,
1154- const char * name , core_object_t * object ,
1155- event_handler_t handler , void * data ) {
1151+ static unsigned long core_object_event_register (const core_object_klass_t klass ,
1152+ const core_object_event_type_t event ,
1153+ const char * name ,
1154+ core_object_t * object ,
1155+ event_handler_t handler ,
1156+ void * data ) {
11561157 core_t * core = (core_t * )data ;
11571158 event_subscription_t * subscription ;
11581159
@@ -1180,35 +1181,32 @@ static int core_object_event_register(const core_object_klass_t klass,
11801181 pthread_mutex_lock (& core -> events .handlers [event ].lock );
11811182 STAILQ_INSERT_TAIL (& core -> events .handlers [event ].list , subscription , entry );
11821183 pthread_mutex_unlock (& core -> events .handlers [event ].lock );
1183- return 0 ;
1184+ return ( unsigned long ) subscription ;
11841185}
11851186
1186- static int core_object_event_unregister (const core_object_klass_t klass ,
1187- const core_object_event_type_t event ,
1188- const char * name , core_object_t * object ,
1189- event_handler_t handler , void * data ) {
1187+ static int core_object_event_unregister (const core_event_token_t token , void * data ) {
11901188 core_t * core = (core_t * )data ;
11911189 event_subscription_t * subscription ;
11921190 event_subscription_t * next ;
1193- core_object_t * obj = core_object_find ( klass , name , core ) ;
1191+ core_object_event_type_t event ;
11941192
1195- pthread_mutex_lock (& core -> events .handlers [event ].lock );
1196- subscription = STAILQ_FIRST (& core -> events .handlers [event ].list );
1197- pthread_mutex_unlock (& core -> events .handlers [event ].lock );
1198- while (subscription != NULL ) {
1199- next = STAILQ_NEXT (subscription , entry );
1200- if (subscription -> klass == klass &&
1201- (subscription -> object_id == CORE_OBJECT_ID_INVALID ||
1202- (object && subscription -> object_id == core_object_to_id (obj )))) {
1203- pthread_mutex_lock (& core -> events .handlers [event ].lock );
1204- STAILQ_REMOVE (& core -> events .handlers [event ].list , subscription ,
1205- event_subscription , entry );
1206- pthread_mutex_unlock (& core -> events .handlers [event ].lock );
1207- free (subscription );
1208- return 0 ;
1209- }
1193+ for (event = OBJECT_EVENT_STEPPER_MOVE_COMPLETE ; event <= OBJECT_EVENT_MAX ; event ++ ) {
1194+ pthread_mutex_lock (& core -> events .handlers [event ].lock );
1195+ subscription = STAILQ_FIRST (& core -> events .handlers [event ].list );
1196+ pthread_mutex_unlock (& core -> events .handlers [event ].lock );
1197+ while (subscription != NULL ) {
1198+ next = STAILQ_NEXT (subscription , entry );
1199+ if ((core_event_token_t )subscription == token ) {
1200+ pthread_mutex_lock (& core -> events .handlers [event ].lock );
1201+ STAILQ_REMOVE (& core -> events .handlers [event ].list , subscription , event_subscription ,
1202+ entry );
1203+ pthread_mutex_unlock (& core -> events .handlers [event ].lock );
1204+ free (subscription );
1205+ return 0 ;
1206+ }
12101207
1211- subscription = next ;
1208+ subscription = next ;
1209+ }
12121210 }
12131211
12141212 return -1 ;
@@ -1272,13 +1270,19 @@ static uint64_t core_object_command_submit(core_object_t *source,
12721270 return (uint64_t )cmd ;
12731271}
12741272
1273+ #define EVENT_TOKEN (klass , type , name , sub ) \
1274+ (core_event_token_t)(((unsigned long)type << 60) | ((unsigned long)sub & ((1UL << 60) - 1)))
1275+
1276+ #define TYPE_FROM_TOKEN (token ) (core_object_event_type_t)((token >> 60) & 0xf)
1277+
12751278static PyObject * vortex_core_python_event_register (PyObject * self ,
12761279 PyObject * args ) {
12771280 core_t * core = (core_t * )self ;
12781281 event_subscription_t * subscription ;
12791282 core_object_klass_t klass ;
12801283 core_object_event_type_t type ;
12811284 PyObject * callback ;
1285+ PyObject * token ;
12821286 char * name = NULL ;
12831287
12841288 if (!PyArg_ParseTuple (args , "iisO" , & klass , & type , & name , & callback ))
@@ -1287,15 +1291,18 @@ static PyObject *vortex_core_python_event_register(PyObject *self,
12871291 Py_INCREF (callback );
12881292
12891293 subscription = calloc (1 , sizeof (* subscription ));
1290- if (!subscription )
1291- Py_RETURN_FALSE ;
1294+ if (!subscription ) {
1295+ Py_DECREF (callback );
1296+ Py_RETURN_NONE ;
1297+ }
12921298
12931299 if (name ) {
12941300 core_object_t * object = core_object_find (klass , name , core );
12951301
12961302 if (!object ) {
12971303 free (subscription );
1298- Py_RETURN_FALSE ;
1304+ Py_DECREF (callback );
1305+ Py_RETURN_NONE ;
12991306 }
13001307
13011308 subscription -> object_id = core_object_to_id (object );
@@ -1309,49 +1316,40 @@ static PyObject *vortex_core_python_event_register(PyObject *self,
13091316 pthread_mutex_lock (& core -> events .handlers [type ].lock );
13101317 STAILQ_INSERT_TAIL (& core -> events .handlers [type ].list , subscription , entry );
13111318 pthread_mutex_unlock (& core -> events .handlers [type ].lock );
1312- Py_RETURN_TRUE ;
1319+ token = Py_BuildValue ("k" , EVENT_TOKEN (klass , type , name , subscription ));
1320+ return token ;
13131321}
13141322
13151323static PyObject * vortex_core_python_event_unregister (PyObject * self ,
13161324 PyObject * args ) {
13171325 core_t * core = (core_t * )self ;
1318- event_subscription_t * subscription ;
1319- event_subscription_t * next ;
1320- core_object_klass_t klass ;
1326+ core_event_token_t subscription ;
13211327 core_object_event_type_t type ;
1322- core_object_id_t object_id = CORE_OBJECT_ID_INVALID ;
1323- char * name ;
1328+ event_subscription_t * iter ;
1329+ event_subscription_t * next ;
13241330
1325- if (PyArg_ParseTuple (args , "iis " , & klass , & type , & name ))
1331+ if (! PyArg_ParseTuple (args , "k " , & subscription ))
13261332 return NULL ;
13271333
1328- if (name ) {
1329- core_object_t * object = core_object_find (klass , name , core );
1330-
1331- if (object )
1332- object_id = core_object_to_id (object );
1333- }
1334+ type = TYPE_FROM_TOKEN (subscription );
13341335
13351336 pthread_mutex_lock (& core -> events .handlers [type ].lock );
1336- subscription = STAILQ_FIRST (& core -> events .handlers [type ].list );
1337+ iter = STAILQ_FIRST (& core -> events .handlers [type ].list );
13371338 pthread_mutex_unlock (& core -> events .handlers [type ].lock );
13381339
1339- while (subscription != NULL ) {
1340- next = STAILQ_NEXT (subscription , entry );
1341- if (subscription -> klass == klass &&
1342- (subscription -> object_id == CORE_OBJECT_ID_INVALID ||
1343- subscription -> object_id == object_id )) {
1340+ while (iter != NULL ) {
1341+ next = STAILQ_NEXT (iter , entry );
1342+ if (subscription == (core_event_token_t )iter ) {
13441343 pthread_mutex_lock (& core -> events .handlers [type ].lock );
1345- STAILQ_REMOVE (& core -> events .handlers [type ].list , subscription ,
1346- event_subscription , entry );
1344+ STAILQ_REMOVE (& core -> events .handlers [type ].list , iter , event_subscription , entry );
13471345 pthread_mutex_unlock (& core -> events .handlers [type ].lock );
1348- if (subscription -> is_python )
1349- Py_DECREF (subscription -> python .handler );
1350- free (subscription );
1346+ if (iter -> is_python )
1347+ Py_DECREF (iter -> python .handler );
1348+ free (iter );
13511349 Py_RETURN_TRUE ;
13521350 }
13531351
1354- subscription = next ;
1352+ iter = next ;
13551353 }
13561354
13571355 Py_RETURN_FALSE ;
0 commit comments