1 /*
2  * Copyright 2016-2017 MongoDB, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <php.h>
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include "phongo_compat.h"
24 #include "php_phongo.h"
25 
ZEND_EXTERN_MODULE_GLOBALS(mongodb)26 ZEND_EXTERN_MODULE_GLOBALS(mongodb)
27 
28 static char* php_phongo_make_subscriber_hash(zval* subscriber)
29 {
30 	char* hash;
31 	int   hash_len;
32 
33 	hash_len = spprintf(&hash, 0, "SUBS-%09d", Z_OBJ_HANDLE_P(subscriber));
34 
35 	return hash;
36 }
37 
38 /* {{{ proto void MongoDB\Driver\Monitoring\addSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber)
39    Adds a monitoring subscriber to the set of subscribers */
PHP_FUNCTION(MongoDB_Driver_Monitoring_addSubscriber)40 PHP_FUNCTION(MongoDB_Driver_Monitoring_addSubscriber)
41 {
42 	zend_error_handling error_handling;
43 	zval*               zSubscriber = NULL;
44 	char*               hash;
45 	zval*               subscriber;
46 
47 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
48 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) {
49 		zend_restore_error_handling(&error_handling);
50 		return;
51 	}
52 	zend_restore_error_handling(&error_handling);
53 
54 	/* The HashTable should never be NULL, as it's initialized during RINIT and
55 	 * destroyed during RSHUTDOWN. This is simply a defensive guard. */
56 	if (!MONGODB_G(subscribers)) {
57 		return;
58 	}
59 
60 	hash = php_phongo_make_subscriber_hash(zSubscriber);
61 
62 	/* If we have already stored the subscriber, bail out. Otherwise, add
63 	 * subscriber to list */
64 	if ((subscriber = zend_hash_str_find(MONGODB_G(subscribers), hash, strlen(hash)))) {
65 		efree(hash);
66 		return;
67 	}
68 
69 	zend_hash_str_update(MONGODB_G(subscribers), hash, strlen(hash), zSubscriber);
70 	Z_ADDREF_P(zSubscriber);
71 	efree(hash);
72 } /* }}} */
73 
74 /* {{{ proto void MongoDB\Driver\Monitoring\removeSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber)
75    Removes a monitoring subscriber from the set of subscribers */
PHP_FUNCTION(MongoDB_Driver_Monitoring_removeSubscriber)76 PHP_FUNCTION(MongoDB_Driver_Monitoring_removeSubscriber)
77 {
78 	zend_error_handling error_handling;
79 	zval*               zSubscriber = NULL;
80 	char*               hash;
81 
82 	zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling);
83 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) {
84 		zend_restore_error_handling(&error_handling);
85 		return;
86 	}
87 	zend_restore_error_handling(&error_handling);
88 
89 	/* The HashTable should never be NULL, as it's initialized during RINIT and
90 	 * destroyed during RSHUTDOWN. This is simply a defensive guard. */
91 	if (!MONGODB_G(subscribers)) {
92 		return;
93 	}
94 
95 	hash = php_phongo_make_subscriber_hash(zSubscriber);
96 
97 	zend_hash_str_del(MONGODB_G(subscribers), hash, strlen(hash));
98 	efree(hash);
99 } /* }}} */
100 
101 /*
102  * Local variables:
103  * tab-width: 4
104  * c-basic-offset: 4
105  * End:
106  * vim600: noet sw=4 ts=4 fdm=marker
107  * vim<600: noet sw=4 ts=4
108  */
109