Просмотр исходного кода

- make tm_stat initialization code aware of possible changes in
process_count value during the mod_init stage

Jan Janak 19 лет назад
Родитель
Сommit
8021d72a85
3 измененных файлов с 64 добавлено и 42 удалено
  1. 49 34
      modules/tm/t_stats.c
  2. 1 0
      modules/tm/t_stats.h
  3. 14 8
      modules/tm/tm.c

+ 49 - 34
modules/tm/t_stats.c

@@ -45,65 +45,80 @@
 
 struct t_stats *tm_stats=0;
 
-
 int init_tm_stats(void)
 {
 	int size;
 
-	tm_stats=shm_malloc(sizeof(struct t_stats));
+	tm_stats = shm_malloc(sizeof(struct t_stats));
 	if (tm_stats==0) {
-		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
-		goto error0;
+		ERR("No mem for stats\n");
+		return -1;
 	}
 	memset(tm_stats, 0, sizeof(struct t_stats) );
 
-	size=sizeof(stat_counter)*process_count;
-	tm_stats->s_waiting=shm_malloc(size);
-	if (tm_stats->s_waiting==0) {
-		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
+	     /* Delay initialization of tm_stats structures to
+	      * init_tm_stats_child which gets called from child_init,
+	      * in mod_init function other modules can increase the value of
+	      * process_count and thus we do not know about processes created
+	      * from modules which get loaded after tm and thus their mod_init
+	      * functions will be called after tm mod_init function finishes
+	      */
+	return 0;
+}
+
+
+int init_tm_stats_child(void)
+{
+	int size;
+
+	     /* We are called from child_init, process_count has definitive
+	      * value now and thus we can safely allocate the variables
+	      */
+	size = sizeof(stat_counter) * process_count;
+	tm_stats->s_waiting = shm_malloc(size);
+	if (tm_stats->s_waiting == 0) {
+		ERR("No mem for stats\n");
 		goto error1;
 	}
-	memset(tm_stats->s_waiting, 0, size );
+	memset(tm_stats->s_waiting, 0, size);
 
-	tm_stats->s_transactions=shm_malloc(size);
-	if (tm_stats->s_transactions==0) {
-		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
+	tm_stats->s_transactions = shm_malloc(size);
+	if (tm_stats->s_transactions == 0) {
+		ERR("No mem for stats\n");
 		goto error2;
 	}
-	memset(tm_stats->s_transactions, 0, size );
+	memset(tm_stats->s_transactions, 0, size);
 
-	tm_stats->s_client_transactions=shm_malloc(size);
-	if (tm_stats->s_client_transactions==0) {
-		LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
+	tm_stats->s_client_transactions = shm_malloc(size);
+	if (tm_stats->s_client_transactions == 0) {
+		ERR("No mem for stats\n");
 		goto error3;
 	}
-	memset(tm_stats->s_client_transactions, 0, size );
-		 
-	return 1;
+	memset(tm_stats->s_client_transactions, 0, size);
+	return 0;
 
-error3:
+ error3:
 	shm_free(tm_stats->s_transactions);
-	tm_stats->s_transactions=0;
-error2:
+	tm_stats->s_transactions = 0;
+ error2:
 	shm_free(tm_stats->s_waiting);
-	tm_stats->s_waiting=0;
-error1:
+	tm_stats->s_waiting = 0;
+ error1:
 	shm_free(tm_stats);
-error0:
 	return -1;
 }
 
+
 void free_tm_stats()
 {
-	if (tm_stats!=0){
-		if (tm_stats->s_client_transactions) 
-			shm_free(tm_stats->s_client_transactions);
-		if (tm_stats->s_transactions)
-			shm_free(tm_stats->s_transactions);
-		if (tm_stats->s_waiting)
-			shm_free(tm_stats->s_waiting);
-		shm_free(tm_stats);
-	}
+	if (tm_stats == 0) return;
+	if (tm_stats->s_client_transactions) 
+		shm_free(tm_stats->s_client_transactions);
+	if (tm_stats->s_transactions)
+		shm_free(tm_stats->s_transactions);
+	if (tm_stats->s_waiting)
+		shm_free(tm_stats->s_waiting);
+	shm_free(tm_stats);
 }
 
 

+ 1 - 0
modules/tm/t_stats.h

@@ -89,6 +89,7 @@ inline static void update_reply_stats( int code ) {
 
 
 int init_tm_stats(void);
+int init_tm_stats_child(void);
 void free_tm_stats();
 
 extern const char* tm_rpc_stats_doc[2];

+ 14 - 8
modules/tm/tm.c

@@ -406,14 +406,13 @@ static int mod_init(void)
 		LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
 		return -1;
 	}
-	/* init_tm_stats calls process_count, which should
-	 * NOT be called from mod_init, because one does not
-	 * now, if a timer is used and thus how many processes
-	 * will be started; however we started already our
-	 * timers, so we know and process_count should not
-	 * change any more
-	 */
-	if (init_tm_stats()<0) {
+
+	     /* First tm_stat initialization function only allocates the top level stat
+	      * structure in shared memory, the initialization will complete in child
+	      * init with init_tm_stats_child when the final value of process_count is
+	      * known
+	      */
+	if (init_tm_stats() < 0) {
 		LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n");
 		return -1;
 	}
@@ -462,6 +461,13 @@ static int child_init(int rank) {
 		return -2;
 	}
 
+	if (rank == PROC_MAIN) {
+		if (init_tm_stats_child() < 0) {
+			ERR("Error while initializing tm statistics structures\n");
+			return -1;
+		}
+	}
+
 	return 0;
 }