@@ -50,6 +50,10 @@ pthread_key_t oauth2_type;
5050pthread_key_t oauth2_token ;
5151pthread_key_t oauth2_token_expires ;
5252
53+ static int oauth2_cache_initialized = FLB_FALSE ;
54+ static int oauth2_cache_users = 0 ;
55+ static pthread_mutex_t oauth2_cache_lock = PTHREAD_MUTEX_INITIALIZER ;
56+
5357static void oauth2_cache_exit (void * ptr )
5458{
5559 if (ptr ) {
@@ -64,12 +68,60 @@ static void oauth2_cache_free_expiration(void *ptr)
6468 }
6569}
6670
67- static void oauth2_cache_init ()
71+ static int oauth2_cache_init ()
6872{
69- /* oauth2 pthread key */
70- pthread_key_create (& oauth2_type , oauth2_cache_exit );
71- pthread_key_create (& oauth2_token , oauth2_cache_exit );
72- pthread_key_create (& oauth2_token_expires , oauth2_cache_free_expiration );
73+ int ret ;
74+
75+ ret = 0 ;
76+
77+ pthread_mutex_lock (& oauth2_cache_lock );
78+
79+ if (oauth2_cache_initialized == FLB_FALSE ) {
80+ /* oauth2 pthread key */
81+ ret = pthread_key_create (& oauth2_type , oauth2_cache_exit );
82+ if (ret != 0 ) {
83+ goto done ;
84+ }
85+ ret = pthread_key_create (& oauth2_token , oauth2_cache_exit );
86+ if (ret != 0 ) {
87+ pthread_key_delete (oauth2_type );
88+ goto done ;
89+ }
90+ ret = pthread_key_create (& oauth2_token_expires ,
91+ oauth2_cache_free_expiration );
92+ if (ret != 0 ) {
93+ pthread_key_delete (oauth2_type );
94+ pthread_key_delete (oauth2_token );
95+ goto done ;
96+ }
97+ oauth2_cache_initialized = FLB_TRUE ;
98+ }
99+
100+ if (ret == 0 ) {
101+ oauth2_cache_users ++ ;
102+ }
103+
104+ done :
105+ pthread_mutex_unlock (& oauth2_cache_lock );
106+ return ret ;
107+ }
108+
109+ static void oauth2_cache_cleanup (void )
110+ {
111+ pthread_mutex_lock (& oauth2_cache_lock );
112+
113+ if (oauth2_cache_users > 0 ) {
114+ oauth2_cache_users -- ;
115+ if (oauth2_cache_users == 0 &&
116+ oauth2_cache_initialized == FLB_TRUE ) {
117+ pthread_key_delete (oauth2_type );
118+ pthread_key_delete (oauth2_token );
119+ pthread_key_delete (oauth2_token_expires );
120+ oauth2_cache_initialized = FLB_FALSE ;
121+ }
122+ }
123+
124+ pthread_mutex_unlock (& oauth2_cache_lock );
73125}
74126
75127/* Set oauth2 type and token in pthread keys */
@@ -1221,7 +1273,7 @@ static int cb_stackdriver_init(struct flb_output_instance *ins,
12211273 /* Load config map */
12221274 ret = flb_output_config_map_set (ins , (void * ) ctx );
12231275 if (ret == -1 ) {
1224- return -1 ;
1276+ goto error ;
12251277 }
12261278
12271279 /* Set context */
@@ -1237,10 +1289,20 @@ static int cb_stackdriver_init(struct flb_output_instance *ins,
12371289 }
12381290
12391291 /* Initialize oauth2 cache pthread keys */
1240- oauth2_cache_init ();
1292+ ret = oauth2_cache_init ();
1293+ if (ret != 0 ) {
1294+ flb_plg_error (ins , "failed to initialize oauth2 cache" );
1295+ goto error ;
1296+ }
1297+ ctx -> oauth2_cache_acquired = FLB_TRUE ;
12411298
12421299 /* Create mutex for acquiring oauth tokens (they are shared across flush coroutines) */
1243- pthread_mutex_init (& ctx -> token_mutex , NULL );
1300+ ret = pthread_mutex_init (& ctx -> token_mutex , NULL );
1301+ if (ret != 0 ) {
1302+ flb_plg_error (ins , "failed to initialize token mutex" );
1303+ goto error ;
1304+ }
1305+ ctx -> token_mutex_initialized = FLB_TRUE ;
12441306
12451307 /* Create Upstream context for Stackdriver Logging (no oauth2 service) */
12461308 ctx -> u = flb_upstream_create_url (config , ctx -> cloud_logging_write_url ,
@@ -1253,15 +1315,15 @@ static int cb_stackdriver_init(struct flb_output_instance *ins,
12531315
12541316 if (!ctx -> u ) {
12551317 flb_plg_error (ctx -> ins , "upstream creation failed" );
1256- return -1 ;
1318+ goto error ;
12571319 }
12581320 if (!ctx -> metadata_u ) {
12591321 flb_plg_error (ctx -> ins , "metadata upstream creation failed" );
1260- return -1 ;
1322+ goto error ;
12611323 }
12621324 if (!ctx -> o ) {
12631325 flb_plg_error (ctx -> ins , "cannot create oauth2 context" );
1264- return -1 ;
1326+ goto error ;
12651327 }
12661328 flb_output_upstream_set (ctx -> u , ins );
12671329
@@ -1282,27 +1344,27 @@ static int cb_stackdriver_init(struct flb_output_instance *ins,
12821344 if (ctx -> metadata_server_auth ) {
12831345 ret = gce_metadata_read_project_id (ctx );
12841346 if (ret == -1 ) {
1285- return -1 ;
1347+ goto error ;
12861348 }
12871349
12881350 if (ctx -> resource_type != RESOURCE_TYPE_GENERIC_NODE
12891351 && ctx -> resource_type != RESOURCE_TYPE_GENERIC_TASK ) {
12901352 ret = gce_metadata_read_zone (ctx );
12911353 if (ret == -1 ) {
1292- return -1 ;
1354+ goto error ;
12931355 }
12941356
12951357 ret = gce_metadata_read_instance_id (ctx );
12961358 if (ret == -1 ) {
1297- return -1 ;
1359+ goto error ;
12981360 }
12991361 }
13001362 }
13011363
13021364 /* Validate project_id */
13031365 if (!ctx -> project_id ) {
13041366 flb_plg_error (ctx -> ins , "property 'project_id' is not set" );
1305- return -1 ;
1367+ goto error ;
13061368 }
13071369
13081370 if (!ctx -> export_to_project_id ) {
@@ -1312,10 +1374,22 @@ static int cb_stackdriver_init(struct flb_output_instance *ins,
13121374 ret = flb_stackdriver_regex_init (ctx );
13131375 if (ret == -1 ) {
13141376 flb_plg_error (ctx -> ins , "failed to init stackdriver custom regex" );
1315- return -1 ;
1377+ goto error ;
13161378 }
13171379
13181380 return 0 ;
1381+
1382+ error :
1383+ if (ctx -> token_mutex_initialized == FLB_TRUE ) {
1384+ pthread_mutex_destroy (& ctx -> token_mutex );
1385+ ctx -> token_mutex_initialized = FLB_FALSE ;
1386+ }
1387+ if (ctx -> oauth2_cache_acquired == FLB_TRUE ) {
1388+ oauth2_cache_cleanup ();
1389+ ctx -> oauth2_cache_acquired = FLB_FALSE ;
1390+ }
1391+ flb_stackdriver_conf_destroy (ctx );
1392+ return -1 ;
13191393}
13201394
13211395static int validate_severity_level (severity_t * s ,
@@ -3087,6 +3161,10 @@ static int cb_stackdriver_exit(void *data, struct flb_config *config)
30873161 return -1 ;
30883162 }
30893163
3164+ if (ctx -> oauth2_cache_acquired == FLB_TRUE ) {
3165+ oauth2_cache_cleanup ();
3166+ ctx -> oauth2_cache_acquired = FLB_FALSE ;
3167+ }
30903168 flb_stackdriver_conf_destroy (ctx );
30913169 return 0 ;
30923170}
0 commit comments