You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zy...@apache.org on 2013/01/15 07:01:34 UTC
[1/3] git commit: TS-977 RecCore: refine P_RecCore.i and rename it to
P_RecCore.cc
TS-977 RecCore: refine P_RecCore.i and rename it to P_RecCore.cc
The suffix of P_RecCore.i is weird for us:
1) cscope can't find the function definition in it by default.
2) using *.i suffix usually indicates that there are something
bad in design. We can share the code gracefully if spliting the
function/class carefully.
Let's refine the code so that we can rename it to P_RecCore.cc safely.
BTW, remove an useless file: ./iocore/utils/diags.i.
I have noticed that there are several test_*.i files which is not so
important for us, just keep it as it is.
Signed-off-by: Yunkai Zhang <qi...@taobao.com>
Signed-off-by: Zhao Yongming <mi...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/3321de50
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/3321de50
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/3321de50
Branch: refs/heads/master
Commit: 3321de5067a9fde8f1b737f96bb1800ce6ace490
Parents: 1199e99
Author: Yunkai Zhang <qi...@taobao.com>
Authored: Thu Jan 10 19:27:50 2013 +0800
Committer: Zhao Yongming <mi...@gmail.com>
Committed: Tue Jan 15 13:41:03 2013 +0800
----------------------------------------------------------------------
lib/records/Makefile.am | 4 +-
lib/records/P_RecCore.cc | 1012 ++++++++++++++++++++++++++++++++++++
lib/records/P_RecCore.h | 8 +-
lib/records/P_RecCore.i | 1074 ---------------------------------------
lib/records/P_RecMessage.h | 2 +-
lib/records/RecLocal.cc | 29 +-
lib/records/RecMessage.cc | 19 +-
lib/records/RecProcess.cc | 46 ++-
8 files changed, 1099 insertions(+), 1095 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/Makefile.am
----------------------------------------------------------------------
diff --git a/lib/records/Makefile.am b/lib/records/Makefile.am
index 3223232..60315f1 100644
--- a/lib/records/Makefile.am
+++ b/lib/records/Makefile.am
@@ -42,7 +42,7 @@ libreclocal_a_SOURCES = \
I_RecSignals.h \
P_RecCompatibility.h \
P_RecCore.h \
- P_RecCore.i \
+ P_RecCore.cc \
P_RecDefs.h \
P_RecLocal.h \
P_RecMessage.h \
@@ -68,7 +68,7 @@ librecprocess_a_SOURCES = \
I_RecSignals.h \
P_RecCompatibility.h \
P_RecCore.h \
- P_RecCore.i \
+ P_RecCore.cc \
P_RecDefs.h \
P_RecMessage.h \
P_RecProcess.h \
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/P_RecCore.cc
----------------------------------------------------------------------
diff --git a/lib/records/P_RecCore.cc b/lib/records/P_RecCore.cc
new file mode 100644
index 0000000..88096e9
--- /dev/null
+++ b/lib/records/P_RecCore.cc
@@ -0,0 +1,1012 @@
+/** @file
+
+ Private record core definitions
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "TextBuffer.h"
+#include "Tokenizer.h"
+#include "ink_string.h"
+
+#include "P_RecCompatibility.h"
+#include "P_RecUtils.h"
+#include "P_RecMessage.h"
+#include "P_RecCore.h"
+
+RecModeT g_mode_type = RECM_NULL;
+
+//-------------------------------------------------------------------------
+// send_set_message
+//-------------------------------------------------------------------------
+static int
+send_set_message(RecRecord * record)
+{
+ RecMessage *m;
+
+ rec_mutex_acquire(&(record->lock));
+ m = RecMessageAlloc(RECG_SET);
+ m = RecMessageMarshal_Realloc(m, record);
+ RecDebug(DL_Note, "[send] RECG_SET [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
+ RecMessageSend(m);
+ RecMessageFree(m);
+ rec_mutex_release(&(record->lock));
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// send_register_message
+//-------------------------------------------------------------------------
+int
+send_register_message(RecRecord * record)
+{
+ RecMessage *m;
+
+ rec_mutex_acquire(&(record->lock));
+ m = RecMessageAlloc(RECG_REGISTER);
+ m = RecMessageMarshal_Realloc(m, record);
+ RecDebug(DL_Note, "[send] RECG_REGISTER [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
+ RecMessageSend(m);
+ RecMessageFree(m);
+ rec_mutex_release(&(record->lock));
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// send_push_message
+//-------------------------------------------------------------------------
+int
+send_push_message()
+{
+ RecRecord *r;
+ RecMessage *m;
+ int i, num_records;
+ bool send_msg = false;
+
+ m = RecMessageAlloc(RECG_PUSH);
+ num_records = g_num_records;
+ for (i = 0; i < num_records; i++) {
+ r = &(g_records[i]);
+ rec_mutex_acquire(&(r->lock));
+ if (i_am_the_record_owner(r->rec_type)) {
+ if (r->sync_required & REC_PEER_SYNC_REQUIRED) {
+ m = RecMessageMarshal_Realloc(m, r);
+ r->sync_required = r->sync_required & ~REC_PEER_SYNC_REQUIRED;
+ send_msg = true;
+ }
+ }
+ rec_mutex_release(&(r->lock));
+ }
+ if (send_msg) {
+ RecDebug(DL_Note, "[send] RECG_PUSH [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
+ RecMessageSend(m);
+ }
+ RecMessageFree(m);
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// send_pull_message
+//-------------------------------------------------------------------------
+int
+send_pull_message(RecMessageT msg_type)
+{
+ RecRecord *r;
+ RecMessage *m;
+ int i, num_records;
+
+ m = RecMessageAlloc(msg_type);
+ switch (msg_type) {
+
+ case RECG_PULL_REQ:
+ // We're requesting all of the records from our peer. No payload
+ // here, just send the message.
+ RecDebug(DL_Note, "[send] RECG_PULL_REQ [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
+ break;
+
+ case RECG_PULL_ACK:
+ // Respond to a RECG_PULL_REQ message from our peer. Send ALL
+ // records! Also be sure to send a response even if it has no
+ // payload. Our peer may be blocking and waiting for a response!
+ num_records = g_num_records;
+ for (i = 0; i < num_records; i++) {
+ r = &(g_records[i]);
+ if (i_am_the_record_owner(r->rec_type) ||
+ (REC_TYPE_IS_STAT(r->rec_type) && !(r->registered)) ||
+ (REC_TYPE_IS_STAT(r->rec_type) && !(r->stat_meta.persist_type != RECP_NON_PERSISTENT))) {
+ rec_mutex_acquire(&(r->lock));
+ m = RecMessageMarshal_Realloc(m, r);
+ r->sync_required = r->sync_required & ~REC_PEER_SYNC_REQUIRED;
+ rec_mutex_release(&(r->lock));
+ }
+ }
+ RecDebug(DL_Note, "[send] RECG_PULL_ACK [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
+ break;
+
+ default:
+ RecMessageFree(m);
+ return REC_ERR_FAIL;
+
+ }
+
+ RecMessageSend(m);
+ RecMessageFree(m);
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// recv_message_cb
+//-------------------------------------------------------------------------
+int
+recv_message_cb(RecMessage * msg, RecMessageT msg_type, void *cookie)
+{
+ REC_NOWARN_UNUSED(cookie);
+
+ RecRecord *r;
+ RecMessageItr itr;
+
+ switch (msg_type) {
+
+ case RECG_SET:
+
+ RecDebug(DL_Note, "[recv] RECG_SET [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
+ if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
+ do {
+ if (REC_TYPE_IS_STAT(r->rec_type)) {
+ RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw));
+ } else {
+ RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), NULL);
+ }
+ } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
+ }
+ break;
+
+ case RECG_REGISTER:
+ RecDebug(DL_Note, "[recv] RECG_REGISTER [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
+ if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
+ do {
+ if (REC_TYPE_IS_STAT(r->rec_type)) {
+ RecRegisterStat(r->rec_type, r->name, r->data_type, r->data_default, r->stat_meta.persist_type);
+ } else if (REC_TYPE_IS_CONFIG(r->rec_type)) {
+ RecRegisterConfig(r->rec_type, r->name, r->data_type,
+ r->data_default, r->config_meta.update_type,
+ r->config_meta.check_type, r->config_meta.check_expr, r->config_meta.access_type);
+ }
+ } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
+ }
+ break;
+
+ case RECG_PUSH:
+ RecDebug(DL_Note, "[recv] RECG_PUSH [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
+ if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
+ do {
+ RecForceInsert(r);
+ } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
+ }
+ break;
+
+ case RECG_PULL_ACK:
+ RecDebug(DL_Note, "[recv] RECG_PULL_ACK [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
+ if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
+ do {
+ RecForceInsert(r);
+ } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
+ }
+ break;
+
+ case RECG_PULL_REQ:
+ RecDebug(DL_Note, "[recv] RECG_PULL_REQ [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
+ send_pull_message(RECG_PULL_ACK);
+ break;
+
+ default:
+ ink_debug_assert(!"Unexpected RecG type");
+ return REC_ERR_FAIL;
+
+ }
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// RecRegisterStatXXX
+//-------------------------------------------------------------------------
+#define REC_REGISTER_STAT_XXX(A, B) \
+ ink_debug_assert((rec_type == RECT_NODE) || \
+ (rec_type == RECT_CLUSTER) || \
+ (rec_type == RECT_PROCESS) || \
+ (rec_type == RECT_LOCAL) || \
+ (rec_type == RECT_PLUGIN)); \
+ RecRecord *r; \
+ RecData my_data_default; \
+ my_data_default.A = data_default; \
+ if ((r = RecRegisterStat(rec_type, name, B, my_data_default, \
+ persist_type)) != NULL) { \
+ if (i_am_the_record_owner(r->rec_type)) { \
+ r->sync_required = r->sync_required | REC_PEER_SYNC_REQUIRED; \
+ } else { \
+ send_register_message(r); \
+ } \
+ return REC_ERR_OKAY; \
+ } else { \
+ return REC_ERR_FAIL; \
+ }
+
+int
+RecRegisterStatInt(RecT rec_type, const char *name, RecInt data_default, RecPersistT persist_type)
+{
+ REC_REGISTER_STAT_XXX(rec_int, RECD_INT);
+}
+
+int
+RecRegisterStatFloat(RecT rec_type, const char *name, RecFloat data_default, RecPersistT persist_type)
+{
+ REC_REGISTER_STAT_XXX(rec_float, RECD_FLOAT);
+}
+
+int
+RecRegisterStatString(RecT rec_type, const char *name, RecString data_default, RecPersistT persist_type)
+{
+ REC_REGISTER_STAT_XXX(rec_string, RECD_STRING);
+}
+
+int
+RecRegisterStatCounter(RecT rec_type, const char *name, RecCounter data_default, RecPersistT persist_type)
+{
+ REC_REGISTER_STAT_XXX(rec_counter, RECD_COUNTER);
+}
+
+
+//-------------------------------------------------------------------------
+// RecRegisterConfigXXX
+//-------------------------------------------------------------------------
+#define REC_REGISTER_CONFIG_XXX(A, B) \
+ RecRecord *r; \
+ RecData my_data_default; \
+ my_data_default.A = data_default; \
+ if ((r = RecRegisterConfig(rec_type, name, B, my_data_default, \
+ update_type, check_type, \
+ check_regex, access_type)) != NULL) { \
+ if (i_am_the_record_owner(r->rec_type)) { \
+ r->sync_required = r->sync_required | REC_PEER_SYNC_REQUIRED; \
+ } else { \
+ send_register_message(r); \
+ } \
+ return REC_ERR_OKAY; \
+ } else { \
+ return REC_ERR_FAIL; \
+ }
+
+int
+RecRegisterConfigInt(RecT rec_type, const char *name,
+ RecInt data_default, RecUpdateT update_type,
+ RecCheckT check_type, const char *check_regex, RecAccessT access_type)
+{
+ ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
+ REC_REGISTER_CONFIG_XXX(rec_int, RECD_INT);
+}
+
+int
+RecRegisterConfigFloat(RecT rec_type, const char *name,
+ RecFloat data_default, RecUpdateT update_type,
+ RecCheckT check_type, const char *check_regex, RecAccessT access_type)
+{
+ ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
+ REC_REGISTER_CONFIG_XXX(rec_float, RECD_FLOAT);
+}
+
+
+int
+RecRegisterConfigString(RecT rec_type, const char *name,
+ const char *data_default_tmp, RecUpdateT update_type,
+ RecCheckT check_type, const char *check_regex, RecAccessT access_type)
+{
+ RecString data_default = (RecString)data_default_tmp;
+ ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
+ REC_REGISTER_CONFIG_XXX(rec_string, RECD_STRING);
+}
+
+int
+RecRegisterConfigCounter(RecT rec_type, const char *name,
+ RecCounter data_default, RecUpdateT update_type,
+ RecCheckT check_type, const char *check_regex, RecAccessT access_type)
+{
+ ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
+ REC_REGISTER_CONFIG_XXX(rec_counter, RECD_COUNTER);
+}
+
+
+//-------------------------------------------------------------------------
+// RecSetRecordXXX
+//-------------------------------------------------------------------------
+int
+RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data, RecRawStat *data_raw, bool lock)
+{
+ int err = REC_ERR_OKAY;
+ RecRecord *r1;
+
+ // FIXME: Most of the time we set, we don't actually need to wrlock
+ // since we are not modifying the g_records_ht.
+ if (lock) {
+ ink_rwlock_wrlock(&g_records_rwlock);
+ }
+
+ if (ink_hash_table_lookup(g_records_ht, name, (void **) &r1)) {
+ if (i_am_the_record_owner(r1->rec_type)) {
+ rec_mutex_acquire(&(r1->lock));
+ if ((data_type != RECD_NULL) && (r1->data_type != data_type)) {
+ err = REC_ERR_FAIL;
+ } else {
+ if (data_type == RECD_NULL) {
+ ink_assert(data->rec_string);
+ switch (r1->data_type) {
+ case RECD_INT:
+ r1->data.rec_int = ink_atoi64(data->rec_string);
+ data_type = RECD_INT;
+ break;
+ case RECD_FLOAT:
+ r1->data.rec_float = atof(data->rec_string);
+ data_type = RECD_FLOAT;
+ break;
+ case RECD_STRING:
+ data_type = RECD_STRING;
+ r1->data.rec_string = data->rec_string;
+ break;
+ case RECD_COUNTER:
+ r1->data.rec_int = ink_atoi64(data->rec_string);
+ data_type = RECD_COUNTER;
+ break;
+ default:
+ err = REC_ERR_FAIL;
+ break;
+ }
+ }
+ g_num_update[r1->rec_type]++;
+
+ if (RecDataSet(data_type, &(r1->data), data)) {
+ r1->sync_required = REC_SYNC_REQUIRED;
+ if (REC_TYPE_IS_CONFIG(r1->rec_type)) {
+ r1->config_meta.update_required = REC_UPDATE_REQUIRED;
+ }
+ }
+ if (REC_TYPE_IS_STAT(r1->rec_type) && (data_raw != NULL)) {
+ r1->stat_meta.data_raw = *data_raw;
+ }
+ }
+ rec_mutex_release(&(r1->lock));
+ } else {
+ // We don't need to ats_strdup() here as we will make copies of any
+ // strings when we marshal them into our RecMessage buffer.
+ RecRecord r2;
+ memset(&r2, 0, sizeof(RecRecord));
+ r2.rec_type = rec_type;
+ r2.name = name;
+ r2.data_type = (data_type != RECD_NULL) ? data_type : r1->data_type;
+ r2.data = *data;
+ if (REC_TYPE_IS_STAT(r2.rec_type) && (data_raw != NULL)) {
+ r2.stat_meta.data_raw = *data_raw;
+ }
+ err = send_set_message(&r2);
+ }
+ } else {
+ // Add the record but do not set the 'registered' flag, as this
+ // record really hasn't been registered yet. Also, in order to
+ // add the record, we need to have a rec_type, so if the user
+ // calls RecSetRecord on a record we haven't registered yet, we
+ // should fail out here.
+ if ((rec_type == RECT_NULL) || (data_type == RECD_NULL)) {
+ err = REC_ERR_FAIL;
+ goto Ldone;
+ }
+ r1 = RecAlloc(rec_type, name, data_type);
+ RecDataSet(data_type, &(r1->data), data);
+ if (REC_TYPE_IS_STAT(r1->rec_type) && (data_raw != NULL)) {
+ r1->stat_meta.data_raw = *data_raw;
+ }
+ if (i_am_the_record_owner(r1->rec_type)) {
+ r1->sync_required = r1->sync_required | REC_PEER_SYNC_REQUIRED;
+ } else {
+ err = send_set_message(r1);
+ }
+ ink_hash_table_insert(g_records_ht, name, (void *) r1);
+
+ }
+
+Ldone:
+ if (lock) {
+ ink_rwlock_unlock(&g_records_rwlock);
+ }
+
+ return err;
+}
+
+int
+RecSetRecordConvert(const char *name, const RecString rec_string, bool lock)
+{
+ RecData data;
+ data.rec_string = rec_string;
+ return RecSetRecord(RECT_NULL, name, RECD_NULL, &data, NULL, lock);
+}
+
+int
+RecSetRecordInt(const char *name, RecInt rec_int, bool lock)
+{
+ RecData data;
+ data.rec_int = rec_int;
+ return RecSetRecord(RECT_NULL, name, RECD_INT, &data, NULL, lock);
+}
+
+int
+RecSetRecordFloat(const char *name, RecFloat rec_float, bool lock)
+{
+ RecData data;
+ data.rec_float = rec_float;
+ return RecSetRecord(RECT_NULL, name, RECD_FLOAT, &data, NULL, lock);
+}
+
+int
+RecSetRecordString(const char *name, const RecString rec_string, bool lock)
+{
+ RecData data;
+ data.rec_string = rec_string;
+ return RecSetRecord(RECT_NULL, name, RECD_STRING, &data, NULL, lock);
+}
+
+int
+RecSetRecordCounter(const char *name, RecCounter rec_counter, bool lock)
+{
+ RecData data;
+ data.rec_counter = rec_counter;
+ return RecSetRecord(RECT_NULL, name, RECD_COUNTER, &data, NULL, lock);
+}
+
+
+//-------------------------------------------------------------------------
+// RecReadStatsFile
+//-------------------------------------------------------------------------
+int
+RecReadStatsFile()
+{
+ RecRecord *r;
+ RecMessage *m;
+ RecMessageItr itr;
+
+ // lock our hash table
+ ink_rwlock_wrlock(&g_records_rwlock);
+
+ if ((m = RecMessageReadFromDisk(g_stats_snap_fpath)) != NULL) {
+ if (RecMessageUnmarshalFirst(m, &itr, &r) != REC_ERR_FAIL) {
+ do {
+ if ((r->name == NULL) || (!strlen(r->name)))
+ continue;
+ RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), false);
+ } while (RecMessageUnmarshalNext(m, &itr, &r) != REC_ERR_FAIL);
+ }
+ }
+
+ ink_rwlock_unlock(&g_records_rwlock);
+ ats_free(m);
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// RecSyncStatsFile
+//-------------------------------------------------------------------------
+int
+RecSyncStatsFile()
+{
+ RecRecord *r;
+ RecMessage *m;
+ int i, num_records;
+ bool sync_to_disk;
+
+ /*
+ * g_mode_type should be initialized by
+ * RecLocalInit() or RecProcessInit() earlier.
+ */
+ ink_assert(g_mode_type != RECM_NULL);
+
+ if (g_mode_type == RECM_SERVER || g_mode_type == RECM_STAND_ALONE) {
+ m = RecMessageAlloc(RECG_NULL);
+ num_records = g_num_records;
+ sync_to_disk = false;
+ for (i = 0; i < num_records; i++) {
+ r = &(g_records[i]);
+ rec_mutex_acquire(&(r->lock));
+ if (REC_TYPE_IS_STAT(r->rec_type)) {
+ if (r->stat_meta.persist_type != RECP_NON_PERSISTENT) {
+ m = RecMessageMarshal_Realloc(m, r);
+ sync_to_disk = true;
+ }
+ }
+ rec_mutex_release(&(r->lock));
+ }
+ if (sync_to_disk) {
+ RecDebug(DL_Note, "Writing '%s' [%d bytes]", g_stats_snap_fpath, m->o_write - m->o_start + sizeof(RecMessageHdr));
+ RecMessageWriteToDisk(m, g_stats_snap_fpath);
+ }
+ RecMessageFree(m);
+ }
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// RecReadConfigFile
+//-------------------------------------------------------------------------
+int
+RecReadConfigFile()
+{
+ char *fbuf;
+ int fsize;
+
+ const char *line;
+ int line_num;
+
+ char *rec_type_str, *name_str, *data_type_str, *data_str;
+ RecT rec_type;
+ RecDataT data_type;
+ RecData data;
+
+ Tokenizer line_tok("\r\n");
+ tok_iter_state line_tok_state;
+
+ RecConfigFileEntry *cfe;
+
+ RecDebug(DL_Note, "Reading '%s'", g_rec_config_fpath);
+
+ // watch out, we're altering our g_rec_config_xxx structures
+ ink_mutex_acquire(&g_rec_config_lock);
+
+ if (RecFileImport_Xmalloc(g_rec_config_fpath, &fbuf, &fsize) == REC_ERR_FAIL) {
+ RecLog(DL_Warning, "Could not import '%s'", g_rec_config_fpath);
+ ink_mutex_release(&g_rec_config_lock);
+ return REC_ERR_FAIL;
+ }
+ // clear our g_rec_config_contents_xxx structures
+ while (!queue_is_empty(g_rec_config_contents_llq)) {
+ cfe = (RecConfigFileEntry *) dequeue(g_rec_config_contents_llq);
+ ats_free(cfe->entry);
+ ats_free(cfe);
+ }
+ ink_hash_table_destroy(g_rec_config_contents_ht);
+ g_rec_config_contents_ht = ink_hash_table_create(InkHashTableKeyType_String);
+
+ // lock our hash table
+ ink_rwlock_wrlock(&g_records_rwlock);
+
+ memset(&data, 0, sizeof(RecData));
+ line_tok.Initialize(fbuf, SHARE_TOKS);
+ line = line_tok.iterFirst(&line_tok_state);
+ line_num = 1;
+ while (line) {
+ char *lc = ats_strdup(line);
+ char *lt = lc;
+ char *ln;
+
+ while (isspace(*lt))
+ lt++;
+ rec_type_str = ink_strtok_r(lt, " \t", &ln);
+
+ // check for blank lines and comments
+ if ((!rec_type_str) || (rec_type_str && (*rec_type_str == '#'))) {
+ goto L_next_line;
+ }
+
+ name_str = ink_strtok_r(NULL, " \t", &ln);
+ data_type_str = ink_strtok_r(NULL, " \t", &ln);
+
+ // extract the string data (a little bit tricker since it can have spaces)
+ if (ln) {
+ // 'ln' will point to either the next token or a bunch of spaces
+ // if the user didn't supply a value (e.g. 'STRING '). First
+ // scan past all of the spaces. If we hit a '\0', then we we
+ // know we didn't have a valid value. If not, set 'data_str' to
+ // the start of the token and scan until we find the end. Once
+ // the end is found, back-peddle to remove any trailing spaces.
+ while (isspace(*ln))
+ ln++;
+ if (*ln == '\0') {
+ data_str = NULL;
+ } else {
+ data_str = ln;
+ while (*ln != '\0')
+ ln++;
+ ln--;
+ while (isspace(*ln) && (ln > data_str))
+ ln--;
+ ln++;
+ *ln = '\0';
+ }
+ } else {
+ data_str = NULL;
+ }
+
+ // check for errors
+ if (!(rec_type_str && name_str && data_type_str && data_str)) {
+ RecLog(DL_Warning, "Could not parse line at '%s:%d' -- skipping line: '%s'", g_rec_config_fpath, line_num, line);
+ goto L_next_line;
+ }
+ // record type
+ rec_type = RECT_NULL;
+ if (strcmp(rec_type_str, "CONFIG") == 0) {
+ rec_type = RECT_CONFIG;
+ } else if (strcmp(rec_type_str, "PROCESS") == 0) {
+ rec_type = RECT_PROCESS;
+ } else if (strcmp(rec_type_str, "NODE") == 0) {
+ rec_type = RECT_NODE;
+ } else if (strcmp(rec_type_str, "CLUSTER") == 0) {
+ rec_type = RECT_CLUSTER;
+ } else if (strcmp(rec_type_str, "LOCAL") == 0) {
+ rec_type = RECT_LOCAL;
+ } else {
+ RecLog(DL_Warning, "Unknown record type '%s' at '%s:%d' -- skipping line", rec_type_str, g_rec_config_fpath, line_num);
+ goto L_next_line;
+ }
+
+ // data_type
+ data_type = RECD_NULL;
+ if (strcmp(data_type_str, "INT") == 0) {
+ data_type = RECD_INT;
+ } else if (strcmp(data_type_str, "FLOAT") == 0) {
+ data_type = RECD_FLOAT;
+ } else if (strcmp(data_type_str, "STRING") == 0) {
+ data_type = RECD_STRING;
+ } else if (strcmp(data_type_str, "COUNTER") == 0) {
+ data_type = RECD_COUNTER;
+ } else {
+ RecLog(DL_Warning, "Unknown data type '%s' at '%s:%d' -- skipping line", data_type_str, g_rec_config_fpath, line_num);
+ goto L_next_line;
+ }
+
+ // set the record
+ RecDataSetFromString(data_type, &data, data_str);
+ RecSetRecord(rec_type, name_str, data_type, &data, NULL, false);
+ RecDataClear(data_type, &data);
+
+ // update our g_rec_config_contents_xxx
+ cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
+ cfe->entry_type = RECE_RECORD;
+ cfe->entry = ats_strdup(name_str);
+ enqueue(g_rec_config_contents_llq, (void *) cfe);
+ ink_hash_table_insert(g_rec_config_contents_ht, name_str, NULL);
+ goto L_done;
+
+ L_next_line:
+ // store this line into g_rec_config_contents_llq so that we can
+ // write it out later
+ cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
+ cfe->entry_type = RECE_COMMENT;
+ cfe->entry = ats_strdup(line);
+ enqueue(g_rec_config_contents_llq, (void *) cfe);
+
+ L_done:
+ line = line_tok.iterNext(&line_tok_state);
+ line_num++;
+ ats_free(lc);
+ }
+
+ // release our hash table
+ ink_rwlock_unlock(&g_records_rwlock);
+ ink_mutex_release(&g_rec_config_lock);
+ ats_free(fbuf);
+
+ return REC_ERR_OKAY;
+}
+
+
+//-------------------------------------------------------------------------
+// RecSyncConfigFile
+//-------------------------------------------------------------------------
+int
+RecSyncConfigToTB(textBuffer * tb)
+{
+ int err = REC_ERR_FAIL;
+
+ /*
+ * g_mode_type should be initialized by
+ * RecLocalInit() or RecProcessInit() earlier.
+ */
+ ink_assert(g_mode_type != RECM_NULL);
+
+ if (g_mode_type == RECM_SERVER || g_mode_type == RECM_STAND_ALONE) {
+ RecRecord *r;
+ int i, num_records;
+ RecConfigFileEntry *cfe;
+ bool sync_to_disk;
+
+ ink_mutex_acquire(&g_rec_config_lock);
+
+ num_records = g_num_records;
+ sync_to_disk = false;
+ for (i = 0; i < num_records; i++) {
+ r = &(g_records[i]);
+ rec_mutex_acquire(&(r->lock));
+ if (REC_TYPE_IS_CONFIG(r->rec_type)) {
+ if (r->sync_required & REC_DISK_SYNC_REQUIRED) {
+ if (!ink_hash_table_isbound(g_rec_config_contents_ht, r->name)) {
+ cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
+ cfe->entry_type = RECE_RECORD;
+ cfe->entry = ats_strdup(r->name);
+ enqueue(g_rec_config_contents_llq, (void *) cfe);
+ ink_hash_table_insert(g_rec_config_contents_ht, r->name, NULL);
+ }
+ r->sync_required = r->sync_required & ~REC_DISK_SYNC_REQUIRED;
+ sync_to_disk = true;
+ }
+ }
+ rec_mutex_release(&(r->lock));
+ }
+
+ if (sync_to_disk) {
+ char b[1024];
+
+ // okay, we're going to write into our textBuffer
+ err = REC_ERR_OKAY;
+ tb->reUse();
+
+ ink_rwlock_rdlock(&g_records_rwlock);
+
+ LLQrec *llq_rec = g_rec_config_contents_llq->head;
+ while (llq_rec != NULL) {
+ cfe = (RecConfigFileEntry *) llq_rec->data;
+ if (cfe->entry_type == RECE_COMMENT) {
+ tb->copyFrom(cfe->entry, strlen(cfe->entry));
+ tb->copyFrom("\n", 1);
+ } else {
+ if (ink_hash_table_lookup(g_records_ht, cfe->entry, (void **) &r)) {
+ rec_mutex_acquire(&(r->lock));
+ // rec_type
+ switch (r->rec_type) {
+ case RECT_CONFIG:
+ tb->copyFrom("CONFIG ", 7);
+ break;
+ case RECT_PROCESS:
+ tb->copyFrom("PROCESS ", 8);
+ break;
+ case RECT_NODE:
+ tb->copyFrom("NODE ", 5);
+ break;
+ case RECT_CLUSTER:
+ tb->copyFrom("CLUSTER ", 8);
+ break;
+ case RECT_LOCAL:
+ tb->copyFrom("LOCAL ", 6);
+ break;
+ default:
+ ink_debug_assert(!"Unexpected RecT type");
+ break;
+ }
+ // name
+ tb->copyFrom(cfe->entry, strlen(cfe->entry));
+ tb->copyFrom(" ", 1);
+ // data_type and value
+ switch (r->data_type) {
+ case RECD_INT:
+ tb->copyFrom("INT ", 4);
+ snprintf(b, 1023, "%" PRId64 "", r->data.rec_int);
+ tb->copyFrom(b, strlen(b));
+ break;
+ case RECD_FLOAT:
+ tb->copyFrom("FLOAT ", 6);
+ snprintf(b, 1023, "%f", r->data.rec_float);
+ tb->copyFrom(b, strlen(b));
+ break;
+ case RECD_STRING:
+ tb->copyFrom("STRING ", 7);
+ if (r->data.rec_string) {
+ tb->copyFrom(r->data.rec_string, strlen(r->data.rec_string));
+ } else {
+ tb->copyFrom("NULL", strlen("NULL"));
+ }
+ break;
+ case RECD_COUNTER:
+ tb->copyFrom("COUNTER ", 8);
+ snprintf(b, 1023, "%" PRId64 "", r->data.rec_counter);
+ tb->copyFrom(b, strlen(b));
+ break;
+ default:
+ ink_debug_assert(!"Unexpected RecD type");
+ break;
+ }
+ tb->copyFrom("\n", 1);
+ rec_mutex_release(&(r->lock));
+ }
+ }
+ llq_rec = llq_rec->next;
+ }
+ ink_rwlock_unlock(&g_records_rwlock);
+ }
+ ink_mutex_release(&g_rec_config_lock);
+ }
+
+ return err;
+}
+
+
+//-------------------------------------------------------------------------
+// RecExecConifgUpdateCbs
+//-------------------------------------------------------------------------
+int
+RecExecConfigUpdateCbs(unsigned int update_required_type)
+{
+ RecRecord *r;
+ int i, num_records;
+
+ num_records = g_num_records;
+ for (i = 0; i < num_records; i++) {
+ r = &(g_records[i]);
+ rec_mutex_acquire(&(r->lock));
+ if (REC_TYPE_IS_CONFIG(r->rec_type)) {
+ /* -- upgrade to support a list of callback functions
+ if ((r->config_meta.update_required & update_required_type) &&
+ (r->config_meta.update_cb)) {
+ (*(r->config_meta.update_cb))(r->name, r->data_type, r->data,
+ r->config_meta.update_cookie);
+ r->config_meta.update_required =
+ r->config_meta.update_required & ~update_required_type;
+ }
+ */
+
+ if ((r->config_meta.update_required & update_required_type) && (r->config_meta.update_cb_list)) {
+ RecConfigUpdateCbList *cur_callback = NULL;
+ for (cur_callback = r->config_meta.update_cb_list; cur_callback; cur_callback = cur_callback->next) {
+ (*(cur_callback->update_cb)) (r->name, r->data_type, r->data, cur_callback->update_cookie);
+ }
+ r->config_meta.update_required = r->config_meta.update_required & ~update_required_type;
+ }
+ }
+ rec_mutex_release(&(r->lock));
+ }
+
+ return REC_ERR_OKAY;
+}
+
+
+//------------------------------------------------------------------------
+// RecResetStatRecord
+//------------------------------------------------------------------------
+int
+RecResetStatRecord(char *name)
+{
+ RecRecord *r1 = NULL;
+ int err = REC_ERR_OKAY;
+
+ if (ink_hash_table_lookup(g_records_ht, name, (void **) &r1)) {
+ if (i_am_the_record_owner(r1->rec_type)) {
+ rec_mutex_acquire(&(r1->lock));
+ RecDataSet(r1->data_type, &(r1->data), &(r1->data_default));
+ rec_mutex_release(&(r1->lock));
+ err = REC_ERR_OKAY;
+ } else {
+ RecRecord r2;
+ memset(&r2, 0, sizeof(RecRecord));
+ r2.rec_type = r1->rec_type;
+ r2.name = r1->name;
+ r2.data_type = r1->data_type;
+ r2.data = r1->data_default;
+
+ err = send_set_message(&r2);
+ }
+ } else {
+ err = REC_ERR_FAIL;
+ }
+
+ return err;
+}
+
+
+//------------------------------------------------------------------------
+// RecResetStatRecord
+//------------------------------------------------------------------------
+int
+RecResetStatRecord(RecT type, bool all)
+{
+ int i, num_records;
+ int err = REC_ERR_OKAY;
+
+ RecDebug(DL_Note, "Reset Statistics Records");
+
+ num_records = g_num_records;
+ for (i = 0; i < num_records; i++) {
+ RecRecord *r1 = &(g_records[i]);
+
+ if (REC_TYPE_IS_STAT(r1->rec_type) && ((type == RECT_NULL) || (r1->rec_type == type)) &&
+ (all || (r1->stat_meta.persist_type != RECP_NON_PERSISTENT)) &&
+ (r1->data_type != RECD_STRING)) {
+ if (i_am_the_record_owner(r1->rec_type)) {
+ rec_mutex_acquire(&(r1->lock));
+ if (!RecDataSet(r1->data_type, &(r1->data), &(r1->data_default))) {
+ err = REC_ERR_FAIL;
+ }
+ rec_mutex_release(&(r1->lock));
+ } else {
+ RecRecord r2;
+ memset(&r2, 0, sizeof(RecRecord));
+ r2.rec_type = r1->rec_type;
+ r2.name = r1->name;
+ r2.data_type = r1->data_type;
+ r2.data = r1->data_default;
+
+ err = send_set_message(&r2);
+ }
+ }
+ }
+ return err;
+}
+
+
+int
+RecSetSyncRequired(char *name, bool lock)
+{
+ int err = REC_ERR_FAIL;
+ RecRecord *r1;
+
+ // FIXME: Most of the time we set, we don't actually need to wrlock
+ // since we are not modifying the g_records_ht.
+ if (lock) {
+ ink_rwlock_wrlock(&g_records_rwlock);
+ }
+
+ if (ink_hash_table_lookup(g_records_ht, name, (void **) &r1)) {
+ if (i_am_the_record_owner(r1->rec_type)) {
+ rec_mutex_acquire(&(r1->lock));
+ r1->sync_required = REC_SYNC_REQUIRED;
+ if (REC_TYPE_IS_CONFIG(r1->rec_type)) {
+ r1->config_meta.update_required = REC_UPDATE_REQUIRED;
+ }
+ rec_mutex_release(&(r1->lock));
+ err = REC_ERR_OKAY;
+ } else {
+ // No point of doing the following because our peer will
+ // set the value with RecDataSet. However, since
+ // r2.name == r1->name, the sync_required bit will not be
+ // set.
+
+ /*
+ RecRecord r2;
+ memset(&r2, 0, sizeof(RecRecord));
+ r2.rec_type = r1->rec_type;
+ r2.name = r1->name;
+ r2.data_type = r1->data_type;
+ r2.data = r1->data_default;
+
+ err = send_set_message(&r2);
+ */
+ }
+ }
+
+ if (lock) {
+ ink_rwlock_unlock(&g_records_rwlock);
+ }
+
+ return err;
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/P_RecCore.h
----------------------------------------------------------------------
diff --git a/lib/records/P_RecCore.h b/lib/records/P_RecCore.h
index 99716d2..fda9b13 100644
--- a/lib/records/P_RecCore.h
+++ b/lib/records/P_RecCore.h
@@ -40,6 +40,7 @@ extern InkHashTable *g_records_ht;
extern ink_rwlock g_records_rwlock;
extern int g_num_records;
extern int g_num_update[];
+extern RecModeT g_mode_type;
extern RecTree *g_records_tree;
// records.config items
@@ -92,7 +93,12 @@ int RecSyncConfigToTB(textBuffer * tb);
// Misc
//-------------------------------------------------------------------------
-int RecExecConfigUpdateCbs();
+bool i_am_the_record_owner(RecT rec_type);
+int send_push_message();
+int send_pull_message(RecMessageT msg_type);
+int send_register_message(RecRecord * record);
+int recv_message_cb(RecMessage * msg, RecMessageT msg_type, void *cookie);
+int RecExecConfigUpdateCbs(unsigned int update_required_type);
int RecExecStatUpdateFuncs();
int RecExecRawStatUpdateFuncs();
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/P_RecCore.i
----------------------------------------------------------------------
diff --git a/lib/records/P_RecCore.i b/lib/records/P_RecCore.i
deleted file mode 100644
index 5e1a27c..0000000
--- a/lib/records/P_RecCore.i
+++ /dev/null
@@ -1,1074 +0,0 @@
-/** @file
-
- Private record core definitions
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-#include "TextBuffer.h"
-#include "Tokenizer.h"
-#include "ink_string.h"
-
-#include "P_RecCompatibility.h"
-#include "P_RecUtils.h"
-
-
-//-------------------------------------------------------------------------
-// i_am_the_record_owner
-//-------------------------------------------------------------------------
-static bool
-i_am_the_record_owner(RecT rec_type)
-{
-#if defined (REC_LOCAL)
-
- switch (rec_type) {
- case RECT_CONFIG:
- case RECT_NODE:
- case RECT_CLUSTER:
- case RECT_LOCAL:
- return true;
- case RECT_PROCESS:
- case RECT_PLUGIN:
- return false;
- default:
- ink_debug_assert(!"Unexpected RecT type");
- return false;
- }
-
-#elif defined (REC_PROCESS)
-
- // g_mode_type is defined in either RecLocal.cc or RecProcess.cc.
- // We can access it since we're inlined by on of these two files.
- if (g_mode_type == RECM_CLIENT) {
- switch (rec_type) {
- case RECT_PROCESS:
- case RECT_PLUGIN:
- return true;
- case RECT_CONFIG:
- case RECT_NODE:
- case RECT_CLUSTER:
- case RECT_LOCAL:
- return false;
- default:
- ink_debug_assert(!"Unexpected RecT type");
- return false;
- }
- } else if (g_mode_type == RECM_STAND_ALONE) {
- switch (rec_type) {
- case RECT_CONFIG:
- case RECT_PROCESS:
- case RECT_NODE:
- case RECT_CLUSTER:
- case RECT_LOCAL:
- case RECT_PLUGIN:
- return true;
- default:
- ink_debug_assert(!"Unexpected RecT type");
- return false;
- }
- }
-#else
-
-#error "Required #define not specificed; expected REC_LOCAL or REC_PROCESS"
-
-#endif
-
- return false;
-}
-
-
-//-------------------------------------------------------------------------
-// send_set_message
-//-------------------------------------------------------------------------
-static int
-send_set_message(RecRecord * record)
-{
- RecMessage *m;
-
- rec_mutex_acquire(&(record->lock));
- m = RecMessageAlloc(RECG_SET);
- m = RecMessageMarshal_Realloc(m, record);
- RecDebug(DL_Note, "[send] RECG_SET [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
- RecMessageSend(m);
- RecMessageFree(m);
- rec_mutex_release(&(record->lock));
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// send_register_message
-//-------------------------------------------------------------------------
-static int
-send_register_message(RecRecord * record)
-{
- RecMessage *m;
-
- rec_mutex_acquire(&(record->lock));
- m = RecMessageAlloc(RECG_REGISTER);
- m = RecMessageMarshal_Realloc(m, record);
- RecDebug(DL_Note, "[send] RECG_REGISTER [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
- RecMessageSend(m);
- RecMessageFree(m);
- rec_mutex_release(&(record->lock));
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// send_push_message
-//-------------------------------------------------------------------------
-static int
-send_push_message()
-{
- RecRecord *r;
- RecMessage *m;
- int i, num_records;
- bool send_msg = false;
-
- m = RecMessageAlloc(RECG_PUSH);
- num_records = g_num_records;
- for (i = 0; i < num_records; i++) {
- r = &(g_records[i]);
- rec_mutex_acquire(&(r->lock));
- if (i_am_the_record_owner(r->rec_type)) {
- if (r->sync_required & REC_PEER_SYNC_REQUIRED) {
- m = RecMessageMarshal_Realloc(m, r);
- r->sync_required = r->sync_required & ~REC_PEER_SYNC_REQUIRED;
- send_msg = true;
- }
- }
- rec_mutex_release(&(r->lock));
- }
- if (send_msg) {
- RecDebug(DL_Note, "[send] RECG_PUSH [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
- RecMessageSend(m);
- }
- RecMessageFree(m);
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// send_pull_message
-//-------------------------------------------------------------------------
-static int
-send_pull_message(RecMessageT msg_type)
-{
- RecRecord *r;
- RecMessage *m;
- int i, num_records;
-
- m = RecMessageAlloc(msg_type);
- switch (msg_type) {
-
- case RECG_PULL_REQ:
- // We're requesting all of the records from our peer. No payload
- // here, just send the message.
- RecDebug(DL_Note, "[send] RECG_PULL_REQ [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
- break;
-
- case RECG_PULL_ACK:
- // Respond to a RECG_PULL_REQ message from our peer. Send ALL
- // records! Also be sure to send a response even if it has no
- // payload. Our peer may be blocking and waiting for a response!
- num_records = g_num_records;
- for (i = 0; i < num_records; i++) {
- r = &(g_records[i]);
- if (i_am_the_record_owner(r->rec_type) ||
- (REC_TYPE_IS_STAT(r->rec_type) && !(r->registered)) ||
- (REC_TYPE_IS_STAT(r->rec_type) && !(r->stat_meta.persist_type != RECP_NON_PERSISTENT))) {
- rec_mutex_acquire(&(r->lock));
- m = RecMessageMarshal_Realloc(m, r);
- r->sync_required = r->sync_required & ~REC_PEER_SYNC_REQUIRED;
- rec_mutex_release(&(r->lock));
- }
- }
- RecDebug(DL_Note, "[send] RECG_PULL_ACK [%d bytes]", sizeof(RecMessageHdr) + m->o_write - m->o_start);
- break;
-
- default:
- RecMessageFree(m);
- return REC_ERR_FAIL;
-
- }
-
- RecMessageSend(m);
- RecMessageFree(m);
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// recv_message_cb
-//-------------------------------------------------------------------------
-static int
-recv_message_cb(RecMessage * msg, RecMessageT msg_type, void *cookie)
-{
- REC_NOWARN_UNUSED(cookie);
-
- RecRecord *r;
- RecMessageItr itr;
-
- switch (msg_type) {
-
- case RECG_SET:
-
- RecDebug(DL_Note, "[recv] RECG_SET [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
- if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
- do {
- if (REC_TYPE_IS_STAT(r->rec_type)) {
- RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw));
- } else {
- RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), NULL);
- }
- } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
- }
- break;
-
- case RECG_REGISTER:
- RecDebug(DL_Note, "[recv] RECG_REGISTER [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
- if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
- do {
- if (REC_TYPE_IS_STAT(r->rec_type)) {
- RecRegisterStat(r->rec_type, r->name, r->data_type, r->data_default, r->stat_meta.persist_type);
- } else if (REC_TYPE_IS_CONFIG(r->rec_type)) {
- RecRegisterConfig(r->rec_type, r->name, r->data_type,
- r->data_default, r->config_meta.update_type,
- r->config_meta.check_type, r->config_meta.check_expr, r->config_meta.access_type);
- }
- } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
- }
- break;
-
- case RECG_PUSH:
- RecDebug(DL_Note, "[recv] RECG_PUSH [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
- if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
- do {
- RecForceInsert(r);
- } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
- }
- break;
-
- case RECG_PULL_ACK:
- RecDebug(DL_Note, "[recv] RECG_PULL_ACK [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
- if (RecMessageUnmarshalFirst(msg, &itr, &r) != REC_ERR_FAIL) {
- do {
- RecForceInsert(r);
- } while (RecMessageUnmarshalNext(msg, &itr, &r) != REC_ERR_FAIL);
- }
- break;
-
- case RECG_PULL_REQ:
- RecDebug(DL_Note, "[recv] RECG_PULL_REQ [%d bytes]", sizeof(RecMessageHdr) + msg->o_end - msg->o_start);
- send_pull_message(RECG_PULL_ACK);
- break;
-
- default:
- ink_debug_assert(!"Unexpected RecG type");
- return REC_ERR_FAIL;
-
- }
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// RecRegisterStatXXX
-//-------------------------------------------------------------------------
-#define REC_REGISTER_STAT_XXX(A, B) \
- ink_debug_assert((rec_type == RECT_NODE) || \
- (rec_type == RECT_CLUSTER) || \
- (rec_type == RECT_PROCESS) || \
- (rec_type == RECT_LOCAL) || \
- (rec_type == RECT_PLUGIN)); \
- RecRecord *r; \
- RecData my_data_default; \
- my_data_default.A = data_default; \
- if ((r = RecRegisterStat(rec_type, name, B, my_data_default, \
- persist_type)) != NULL) { \
- if (i_am_the_record_owner(r->rec_type)) { \
- r->sync_required = r->sync_required | REC_PEER_SYNC_REQUIRED; \
- } else { \
- send_register_message(r); \
- } \
- return REC_ERR_OKAY; \
- } else { \
- return REC_ERR_FAIL; \
- }
-
-int
-RecRegisterStatInt(RecT rec_type, const char *name, RecInt data_default, RecPersistT persist_type)
-{
- REC_REGISTER_STAT_XXX(rec_int, RECD_INT);
-}
-
-int
-RecRegisterStatFloat(RecT rec_type, const char *name, RecFloat data_default, RecPersistT persist_type)
-{
- REC_REGISTER_STAT_XXX(rec_float, RECD_FLOAT);
-}
-
-int
-RecRegisterStatString(RecT rec_type, const char *name, RecString data_default, RecPersistT persist_type)
-{
- REC_REGISTER_STAT_XXX(rec_string, RECD_STRING);
-}
-
-int
-RecRegisterStatCounter(RecT rec_type, const char *name, RecCounter data_default, RecPersistT persist_type)
-{
- REC_REGISTER_STAT_XXX(rec_counter, RECD_COUNTER);
-}
-
-
-//-------------------------------------------------------------------------
-// RecRegisterConfigXXX
-//-------------------------------------------------------------------------
-#define REC_REGISTER_CONFIG_XXX(A, B) \
- RecRecord *r; \
- RecData my_data_default; \
- my_data_default.A = data_default; \
- if ((r = RecRegisterConfig(rec_type, name, B, my_data_default, \
- update_type, check_type, \
- check_regex, access_type)) != NULL) { \
- if (i_am_the_record_owner(r->rec_type)) { \
- r->sync_required = r->sync_required | REC_PEER_SYNC_REQUIRED; \
- } else { \
- send_register_message(r); \
- } \
- return REC_ERR_OKAY; \
- } else { \
- return REC_ERR_FAIL; \
- }
-
-int
-RecRegisterConfigInt(RecT rec_type, const char *name,
- RecInt data_default, RecUpdateT update_type,
- RecCheckT check_type, const char *check_regex, RecAccessT access_type)
-{
- ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
- REC_REGISTER_CONFIG_XXX(rec_int, RECD_INT);
-}
-
-int
-RecRegisterConfigFloat(RecT rec_type, const char *name,
- RecFloat data_default, RecUpdateT update_type,
- RecCheckT check_type, const char *check_regex, RecAccessT access_type)
-{
- ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
- REC_REGISTER_CONFIG_XXX(rec_float, RECD_FLOAT);
-}
-
-
-int
-RecRegisterConfigString(RecT rec_type, const char *name,
- const char *data_default_tmp, RecUpdateT update_type,
- RecCheckT check_type, const char *check_regex, RecAccessT access_type)
-{
- RecString data_default = (RecString)data_default_tmp;
- ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
- REC_REGISTER_CONFIG_XXX(rec_string, RECD_STRING);
-}
-
-int
-RecRegisterConfigCounter(RecT rec_type, const char *name,
- RecCounter data_default, RecUpdateT update_type,
- RecCheckT check_type, const char *check_regex, RecAccessT access_type)
-{
- ink_debug_assert((rec_type == RECT_CONFIG) || (rec_type == RECT_LOCAL));
- REC_REGISTER_CONFIG_XXX(rec_counter, RECD_COUNTER);
-}
-
-
-//-------------------------------------------------------------------------
-// RecSetRecordXXX
-//-------------------------------------------------------------------------
-int
-RecSetRecord(RecT rec_type, const char *name, RecDataT data_type, RecData *data, RecRawStat *data_raw, bool lock)
-{
- int err = REC_ERR_OKAY;
- RecRecord *r1;
-
- // FIXME: Most of the time we set, we don't actually need to wrlock
- // since we are not modifying the g_records_ht.
- if (lock) {
- ink_rwlock_wrlock(&g_records_rwlock);
- }
-
- if (ink_hash_table_lookup(g_records_ht, name, (void **) &r1)) {
- if (i_am_the_record_owner(r1->rec_type)) {
- rec_mutex_acquire(&(r1->lock));
- if ((data_type != RECD_NULL) && (r1->data_type != data_type)) {
- err = REC_ERR_FAIL;
- } else {
- if (data_type == RECD_NULL) {
- ink_assert(data->rec_string);
- switch (r1->data_type) {
- case RECD_INT:
- r1->data.rec_int = ink_atoi64(data->rec_string);
- data_type = RECD_INT;
- break;
- case RECD_FLOAT:
- r1->data.rec_float = atof(data->rec_string);
- data_type = RECD_FLOAT;
- break;
- case RECD_STRING:
- data_type = RECD_STRING;
- r1->data.rec_string = data->rec_string;
- break;
- case RECD_COUNTER:
- r1->data.rec_int = ink_atoi64(data->rec_string);
- data_type = RECD_COUNTER;
- break;
- default:
- err = REC_ERR_FAIL;
- break;
- }
- }
- g_num_update[r1->rec_type]++;
-
- if (RecDataSet(data_type, &(r1->data), data)) {
- r1->sync_required = REC_SYNC_REQUIRED;
- if (REC_TYPE_IS_CONFIG(r1->rec_type)) {
- r1->config_meta.update_required = REC_UPDATE_REQUIRED;
- }
- }
- if (REC_TYPE_IS_STAT(r1->rec_type) && (data_raw != NULL)) {
- r1->stat_meta.data_raw = *data_raw;
- }
- }
- rec_mutex_release(&(r1->lock));
- } else {
- // We don't need to ats_strdup() here as we will make copies of any
- // strings when we marshal them into our RecMessage buffer.
- RecRecord r2;
- memset(&r2, 0, sizeof(RecRecord));
- r2.rec_type = rec_type;
- r2.name = name;
- r2.data_type = (data_type != RECD_NULL) ? data_type : r1->data_type;
- r2.data = *data;
- if (REC_TYPE_IS_STAT(r2.rec_type) && (data_raw != NULL)) {
- r2.stat_meta.data_raw = *data_raw;
- }
- err = send_set_message(&r2);
- }
- } else {
- // Add the record but do not set the 'registered' flag, as this
- // record really hasn't been registered yet. Also, in order to
- // add the record, we need to have a rec_type, so if the user
- // calls RecSetRecord on a record we haven't registered yet, we
- // should fail out here.
- if ((rec_type == RECT_NULL) || (data_type == RECD_NULL)) {
- err = REC_ERR_FAIL;
- goto Ldone;
- }
- r1 = RecAlloc(rec_type, name, data_type);
- RecDataSet(data_type, &(r1->data), data);
- if (REC_TYPE_IS_STAT(r1->rec_type) && (data_raw != NULL)) {
- r1->stat_meta.data_raw = *data_raw;
- }
- if (i_am_the_record_owner(r1->rec_type)) {
- r1->sync_required = r1->sync_required | REC_PEER_SYNC_REQUIRED;
- } else {
- err = send_set_message(r1);
- }
- ink_hash_table_insert(g_records_ht, name, (void *) r1);
-
- }
-
-Ldone:
- if (lock) {
- ink_rwlock_unlock(&g_records_rwlock);
- }
-
- return err;
-}
-
-int
-RecSetRecordConvert(const char *name, const RecString rec_string, bool lock)
-{
- RecData data;
- data.rec_string = rec_string;
- return RecSetRecord(RECT_NULL, name, RECD_NULL, &data, NULL, lock);
-}
-
-int
-RecSetRecordInt(const char *name, RecInt rec_int, bool lock)
-{
- RecData data;
- data.rec_int = rec_int;
- return RecSetRecord(RECT_NULL, name, RECD_INT, &data, NULL, lock);
-}
-
-int
-RecSetRecordFloat(const char *name, RecFloat rec_float, bool lock)
-{
- RecData data;
- data.rec_float = rec_float;
- return RecSetRecord(RECT_NULL, name, RECD_FLOAT, &data, NULL, lock);
-}
-
-int
-RecSetRecordString(const char *name, const RecString rec_string, bool lock)
-{
- RecData data;
- data.rec_string = rec_string;
- return RecSetRecord(RECT_NULL, name, RECD_STRING, &data, NULL, lock);
-}
-
-int
-RecSetRecordCounter(const char *name, RecCounter rec_counter, bool lock)
-{
- RecData data;
- data.rec_counter = rec_counter;
- return RecSetRecord(RECT_NULL, name, RECD_COUNTER, &data, NULL, lock);
-}
-
-
-//-------------------------------------------------------------------------
-// RecReadStatsFile
-//-------------------------------------------------------------------------
-int
-RecReadStatsFile()
-{
- RecRecord *r;
- RecMessage *m;
- RecMessageItr itr;
-
- // lock our hash table
- ink_rwlock_wrlock(&g_records_rwlock);
-
- if ((m = RecMessageReadFromDisk(g_stats_snap_fpath)) != NULL) {
- if (RecMessageUnmarshalFirst(m, &itr, &r) != REC_ERR_FAIL) {
- do {
- if ((r->name == NULL) || (!strlen(r->name)))
- continue;
- RecSetRecord(r->rec_type, r->name, r->data_type, &(r->data), &(r->stat_meta.data_raw), false);
- } while (RecMessageUnmarshalNext(m, &itr, &r) != REC_ERR_FAIL);
- }
- }
-
- ink_rwlock_unlock(&g_records_rwlock);
- ats_free(m);
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// RecSyncStatsFile
-//-------------------------------------------------------------------------
-int
-RecSyncStatsFile()
-{
- RecRecord *r;
- RecMessage *m;
- int i, num_records;
- bool sync_to_disk;
-
- // g_mode_type is defined in either RecLocal.cc or RecProcess.cc.
- // We can access it since we're inlined by on of these two files.
- if (g_mode_type == RECM_SERVER || g_mode_type == RECM_STAND_ALONE) {
- m = RecMessageAlloc(RECG_NULL);
- num_records = g_num_records;
- sync_to_disk = false;
- for (i = 0; i < num_records; i++) {
- r = &(g_records[i]);
- rec_mutex_acquire(&(r->lock));
- if (REC_TYPE_IS_STAT(r->rec_type)) {
- if (r->stat_meta.persist_type != RECP_NON_PERSISTENT) {
- m = RecMessageMarshal_Realloc(m, r);
- sync_to_disk = true;
- }
- }
- rec_mutex_release(&(r->lock));
- }
- if (sync_to_disk) {
- RecDebug(DL_Note, "Writing '%s' [%d bytes]", g_stats_snap_fpath, m->o_write - m->o_start + sizeof(RecMessageHdr));
- RecMessageWriteToDisk(m, g_stats_snap_fpath);
- }
- RecMessageFree(m);
- }
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// RecReadConfigFile
-//-------------------------------------------------------------------------
-int
-RecReadConfigFile()
-{
- char *fbuf;
- int fsize;
-
- const char *line;
- int line_num;
-
- char *rec_type_str, *name_str, *data_type_str, *data_str;
- RecT rec_type;
- RecDataT data_type;
- RecData data;
-
- Tokenizer line_tok("\r\n");
- tok_iter_state line_tok_state;
-
- RecConfigFileEntry *cfe;
-
- RecDebug(DL_Note, "Reading '%s'", g_rec_config_fpath);
-
- // watch out, we're altering our g_rec_config_xxx structures
- ink_mutex_acquire(&g_rec_config_lock);
-
- if (RecFileImport_Xmalloc(g_rec_config_fpath, &fbuf, &fsize) == REC_ERR_FAIL) {
- RecLog(DL_Warning, "Could not import '%s'", g_rec_config_fpath);
- ink_mutex_release(&g_rec_config_lock);
- return REC_ERR_FAIL;
- }
- // clear our g_rec_config_contents_xxx structures
- while (!queue_is_empty(g_rec_config_contents_llq)) {
- cfe = (RecConfigFileEntry *) dequeue(g_rec_config_contents_llq);
- ats_free(cfe->entry);
- ats_free(cfe);
- }
- ink_hash_table_destroy(g_rec_config_contents_ht);
- g_rec_config_contents_ht = ink_hash_table_create(InkHashTableKeyType_String);
-
- // lock our hash table
- ink_rwlock_wrlock(&g_records_rwlock);
-
- memset(&data, 0, sizeof(RecData));
- line_tok.Initialize(fbuf, SHARE_TOKS);
- line = line_tok.iterFirst(&line_tok_state);
- line_num = 1;
- while (line) {
- char *lc = ats_strdup(line);
- char *lt = lc;
- char *ln;
-
- while (isspace(*lt))
- lt++;
- rec_type_str = ink_strtok_r(lt, " \t", &ln);
-
- // check for blank lines and comments
- if ((!rec_type_str) || (rec_type_str && (*rec_type_str == '#'))) {
- goto L_next_line;
- }
-
- name_str = ink_strtok_r(NULL, " \t", &ln);
- data_type_str = ink_strtok_r(NULL, " \t", &ln);
-
- // extract the string data (a little bit tricker since it can have spaces)
- if (ln) {
- // 'ln' will point to either the next token or a bunch of spaces
- // if the user didn't supply a value (e.g. 'STRING '). First
- // scan past all of the spaces. If we hit a '\0', then we we
- // know we didn't have a valid value. If not, set 'data_str' to
- // the start of the token and scan until we find the end. Once
- // the end is found, back-peddle to remove any trailing spaces.
- while (isspace(*ln))
- ln++;
- if (*ln == '\0') {
- data_str = NULL;
- } else {
- data_str = ln;
- while (*ln != '\0')
- ln++;
- ln--;
- while (isspace(*ln) && (ln > data_str))
- ln--;
- ln++;
- *ln = '\0';
- }
- } else {
- data_str = NULL;
- }
-
- // check for errors
- if (!(rec_type_str && name_str && data_type_str && data_str)) {
- RecLog(DL_Warning, "Could not parse line at '%s:%d' -- skipping line: '%s'", g_rec_config_fpath, line_num, line);
- goto L_next_line;
- }
- // record type
- rec_type = RECT_NULL;
- if (strcmp(rec_type_str, "CONFIG") == 0) {
- rec_type = RECT_CONFIG;
- } else if (strcmp(rec_type_str, "PROCESS") == 0) {
- rec_type = RECT_PROCESS;
- } else if (strcmp(rec_type_str, "NODE") == 0) {
- rec_type = RECT_NODE;
- } else if (strcmp(rec_type_str, "CLUSTER") == 0) {
- rec_type = RECT_CLUSTER;
- } else if (strcmp(rec_type_str, "LOCAL") == 0) {
- rec_type = RECT_LOCAL;
- } else {
- RecLog(DL_Warning, "Unknown record type '%s' at '%s:%d' -- skipping line", rec_type_str, g_rec_config_fpath, line_num);
- goto L_next_line;
- }
-
- // data_type
- data_type = RECD_NULL;
- if (strcmp(data_type_str, "INT") == 0) {
- data_type = RECD_INT;
- } else if (strcmp(data_type_str, "FLOAT") == 0) {
- data_type = RECD_FLOAT;
- } else if (strcmp(data_type_str, "STRING") == 0) {
- data_type = RECD_STRING;
- } else if (strcmp(data_type_str, "COUNTER") == 0) {
- data_type = RECD_COUNTER;
- } else {
- RecLog(DL_Warning, "Unknown data type '%s' at '%s:%d' -- skipping line", data_type_str, g_rec_config_fpath, line_num);
- goto L_next_line;
- }
-
- // set the record
- RecDataSetFromString(data_type, &data, data_str);
- RecSetRecord(rec_type, name_str, data_type, &data, NULL, false);
- RecDataClear(data_type, &data);
-
- // update our g_rec_config_contents_xxx
- cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
- cfe->entry_type = RECE_RECORD;
- cfe->entry = ats_strdup(name_str);
- enqueue(g_rec_config_contents_llq, (void *) cfe);
- ink_hash_table_insert(g_rec_config_contents_ht, name_str, NULL);
- goto L_done;
-
- L_next_line:
- // store this line into g_rec_config_contents_llq so that we can
- // write it out later
- cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
- cfe->entry_type = RECE_COMMENT;
- cfe->entry = ats_strdup(line);
- enqueue(g_rec_config_contents_llq, (void *) cfe);
-
- L_done:
- line = line_tok.iterNext(&line_tok_state);
- line_num++;
- ats_free(lc);
- }
-
- // release our hash table
- ink_rwlock_unlock(&g_records_rwlock);
- ink_mutex_release(&g_rec_config_lock);
- ats_free(fbuf);
-
- return REC_ERR_OKAY;
-}
-
-
-//-------------------------------------------------------------------------
-// RecSyncConfigFile
-//-------------------------------------------------------------------------
-int
-RecSyncConfigToTB(textBuffer * tb)
-{
- int err = REC_ERR_FAIL;
-
- // g_mode_type is defined in either RecLocal.cc or RecProcess.cc.
- // We can access it since we're inlined by on of these two files.
- if (g_mode_type == RECM_SERVER || g_mode_type == RECM_STAND_ALONE) {
- RecRecord *r;
- int i, num_records;
- RecConfigFileEntry *cfe;
- bool sync_to_disk;
-
- ink_mutex_acquire(&g_rec_config_lock);
-
- num_records = g_num_records;
- sync_to_disk = false;
- for (i = 0; i < num_records; i++) {
- r = &(g_records[i]);
- rec_mutex_acquire(&(r->lock));
- if (REC_TYPE_IS_CONFIG(r->rec_type)) {
- if (r->sync_required & REC_DISK_SYNC_REQUIRED) {
- if (!ink_hash_table_isbound(g_rec_config_contents_ht, r->name)) {
- cfe = (RecConfigFileEntry *)ats_malloc(sizeof(RecConfigFileEntry));
- cfe->entry_type = RECE_RECORD;
- cfe->entry = ats_strdup(r->name);
- enqueue(g_rec_config_contents_llq, (void *) cfe);
- ink_hash_table_insert(g_rec_config_contents_ht, r->name, NULL);
- }
- r->sync_required = r->sync_required & ~REC_DISK_SYNC_REQUIRED;
- sync_to_disk = true;
- }
- }
- rec_mutex_release(&(r->lock));
- }
-
- if (sync_to_disk) {
- char b[1024];
-
- // okay, we're going to write into our textBuffer
- err = REC_ERR_OKAY;
- tb->reUse();
-
- ink_rwlock_rdlock(&g_records_rwlock);
-
- LLQrec *llq_rec = g_rec_config_contents_llq->head;
- while (llq_rec != NULL) {
- cfe = (RecConfigFileEntry *) llq_rec->data;
- if (cfe->entry_type == RECE_COMMENT) {
- tb->copyFrom(cfe->entry, strlen(cfe->entry));
- tb->copyFrom("\n", 1);
- } else {
- if (ink_hash_table_lookup(g_records_ht, cfe->entry, (void **) &r)) {
- rec_mutex_acquire(&(r->lock));
- // rec_type
- switch (r->rec_type) {
- case RECT_CONFIG:
- tb->copyFrom("CONFIG ", 7);
- break;
- case RECT_PROCESS:
- tb->copyFrom("PROCESS ", 8);
- break;
- case RECT_NODE:
- tb->copyFrom("NODE ", 5);
- break;
- case RECT_CLUSTER:
- tb->copyFrom("CLUSTER ", 8);
- break;
- case RECT_LOCAL:
- tb->copyFrom("LOCAL ", 6);
- break;
- default:
- ink_debug_assert(!"Unexpected RecT type");
- break;
- }
- // name
- tb->copyFrom(cfe->entry, strlen(cfe->entry));
- tb->copyFrom(" ", 1);
- // data_type and value
- switch (r->data_type) {
- case RECD_INT:
- tb->copyFrom("INT ", 4);
- snprintf(b, 1023, "%" PRId64 "", r->data.rec_int);
- tb->copyFrom(b, strlen(b));
- break;
- case RECD_FLOAT:
- tb->copyFrom("FLOAT ", 6);
- snprintf(b, 1023, "%f", r->data.rec_float);
- tb->copyFrom(b, strlen(b));
- break;
- case RECD_STRING:
- tb->copyFrom("STRING ", 7);
- if (r->data.rec_string) {
- tb->copyFrom(r->data.rec_string, strlen(r->data.rec_string));
- } else {
- tb->copyFrom("NULL", strlen("NULL"));
- }
- break;
- case RECD_COUNTER:
- tb->copyFrom("COUNTER ", 8);
- snprintf(b, 1023, "%" PRId64 "", r->data.rec_counter);
- tb->copyFrom(b, strlen(b));
- break;
- default:
- ink_debug_assert(!"Unexpected RecD type");
- break;
- }
- tb->copyFrom("\n", 1);
- rec_mutex_release(&(r->lock));
- }
- }
- llq_rec = llq_rec->next;
- }
- ink_rwlock_unlock(&g_records_rwlock);
- }
- ink_mutex_release(&g_rec_config_lock);
- }
-
- return err;
-}
-
-
-//-------------------------------------------------------------------------
-// RecExecConifgUpdateCbs
-//-------------------------------------------------------------------------
-int
-RecExecConfigUpdateCbs()
-{
- RecRecord *r;
- int i, num_records;
- unsigned int update_required_type;
-
-#if defined (REC_LOCAL)
- update_required_type = REC_LOCAL_UPDATE_REQUIRED;
-#elif defined (REC_PROCESS)
- update_required_type = REC_PROCESS_UPDATE_REQUIRED;
-#else
-#error "Required #define not specificed; expected REC_LOCAL or REC_PROCESS"
-#endif
-
- num_records = g_num_records;
- for (i = 0; i < num_records; i++) {
- r = &(g_records[i]);
- rec_mutex_acquire(&(r->lock));
- if (REC_TYPE_IS_CONFIG(r->rec_type)) {
- /* -- upgrade to support a list of callback functions
- if ((r->config_meta.update_required & update_required_type) &&
- (r->config_meta.update_cb)) {
- (*(r->config_meta.update_cb))(r->name, r->data_type, r->data,
- r->config_meta.update_cookie);
- r->config_meta.update_required =
- r->config_meta.update_required & ~update_required_type;
- }
- */
-
- if ((r->config_meta.update_required & update_required_type) && (r->config_meta.update_cb_list)) {
- RecConfigUpdateCbList *cur_callback = NULL;
- for (cur_callback = r->config_meta.update_cb_list; cur_callback; cur_callback = cur_callback->next) {
- (*(cur_callback->update_cb)) (r->name, r->data_type, r->data, cur_callback->update_cookie);
- }
- r->config_meta.update_required = r->config_meta.update_required & ~update_required_type;
- }
- }
- rec_mutex_release(&(r->lock));
- }
-
- return REC_ERR_OKAY;
-}
-
-
-//------------------------------------------------------------------------
-// RecResetStatRecord
-//------------------------------------------------------------------------
-int
-RecResetStatRecord(char *name)
-{
- RecRecord *r1 = NULL;
- int err = REC_ERR_OKAY;
-
- if (ink_hash_table_lookup(g_records_ht, name, (void **) &r1)) {
- if (i_am_the_record_owner(r1->rec_type)) {
- rec_mutex_acquire(&(r1->lock));
- RecDataSet(r1->data_type, &(r1->data), &(r1->data_default));
- rec_mutex_release(&(r1->lock));
- err = REC_ERR_OKAY;
- } else {
- RecRecord r2;
- memset(&r2, 0, sizeof(RecRecord));
- r2.rec_type = r1->rec_type;
- r2.name = r1->name;
- r2.data_type = r1->data_type;
- r2.data = r1->data_default;
-
- err = send_set_message(&r2);
- }
- } else {
- err = REC_ERR_FAIL;
- }
-
- return err;
-}
-
-
-//------------------------------------------------------------------------
-// RecResetStatRecord
-//------------------------------------------------------------------------
-int
-RecResetStatRecord(RecT type, bool all)
-{
- int i, num_records;
- int err = REC_ERR_OKAY;
-
- RecDebug(DL_Note, "Reset Statistics Records");
-
- num_records = g_num_records;
- for (i = 0; i < num_records; i++) {
- RecRecord *r1 = &(g_records[i]);
-
- if (REC_TYPE_IS_STAT(r1->rec_type) && ((type == RECT_NULL) || (r1->rec_type == type)) &&
- (all || (r1->stat_meta.persist_type != RECP_NON_PERSISTENT)) &&
- (r1->data_type != RECD_STRING)) {
- if (i_am_the_record_owner(r1->rec_type)) {
- rec_mutex_acquire(&(r1->lock));
- if (!RecDataSet(r1->data_type, &(r1->data), &(r1->data_default))) {
- err = REC_ERR_FAIL;
- }
- rec_mutex_release(&(r1->lock));
- } else {
- RecRecord r2;
- memset(&r2, 0, sizeof(RecRecord));
- r2.rec_type = r1->rec_type;
- r2.name = r1->name;
- r2.data_type = r1->data_type;
- r2.data = r1->data_default;
-
- err = send_set_message(&r2);
- }
- }
- }
- return err;
-}
-
-
-int
-RecSetSyncRequired(char *name, bool lock)
-{
- int err = REC_ERR_FAIL;
- RecRecord *r1;
-
- // FIXME: Most of the time we set, we don't actually need to wrlock
- // since we are not modifying the g_records_ht.
- if (lock) {
- ink_rwlock_wrlock(&g_records_rwlock);
- }
-
- if (ink_hash_table_lookup(g_records_ht, name, (void **) &r1)) {
- if (i_am_the_record_owner(r1->rec_type)) {
- rec_mutex_acquire(&(r1->lock));
- r1->sync_required = REC_SYNC_REQUIRED;
- if (REC_TYPE_IS_CONFIG(r1->rec_type)) {
- r1->config_meta.update_required = REC_UPDATE_REQUIRED;
- }
- rec_mutex_release(&(r1->lock));
- err = REC_ERR_OKAY;
- } else {
- // No point of doing the following because our peer will
- // set the value with RecDataSet. However, since
- // r2.name == r1->name, the sync_required bit will not be
- // set.
-
- /*
- RecRecord r2;
- memset(&r2, 0, sizeof(RecRecord));
- r2.rec_type = r1->rec_type;
- r2.name = r1->name;
- r2.data_type = r1->data_type;
- r2.data = r1->data_default;
-
- err = send_set_message(&r2);
- */
- }
- }
-
- if (lock) {
- ink_rwlock_unlock(&g_records_rwlock);
- }
-
- return err;
-}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/P_RecMessage.h
----------------------------------------------------------------------
diff --git a/lib/records/P_RecMessage.h b/lib/records/P_RecMessage.h
index 713d886..be7dcc6 100644
--- a/lib/records/P_RecMessage.h
+++ b/lib/records/P_RecMessage.h
@@ -30,7 +30,7 @@
// Initialization
//-------------------------------------------------------------------------
-int RecMessageInit(RecModeT mode);
+int RecMessageInit();
//-------------------------------------------------------------------------
// Message Operations
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/RecLocal.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecLocal.cc b/lib/records/RecLocal.cc
index 6bc77c8..90cee83 100644
--- a/lib/records/RecLocal.cc
+++ b/lib/records/RecLocal.cc
@@ -27,14 +27,31 @@
#include "P_RecLocal.h"
#include "P_RecMessage.h"
#include "P_RecUtils.h"
+#include "P_RecCompatibility.h"
static bool g_initialized = false;
static bool g_message_initialized = false;
-static RecModeT g_mode_type = RECM_NULL;
-#define REC_LOCAL
-#include "P_RecCore.i"
-#undef REC_LOCAL
+//-------------------------------------------------------------------------
+// i_am_the_record_owner, only used for libreclocal.a
+//-------------------------------------------------------------------------
+bool
+i_am_the_record_owner(RecT rec_type)
+{
+ switch (rec_type) {
+ case RECT_CONFIG:
+ case RECT_NODE:
+ case RECT_CLUSTER:
+ case RECT_LOCAL:
+ return true;
+ case RECT_PROCESS:
+ case RECT_PLUGIN:
+ return false;
+ default:
+ ink_debug_assert(!"Unexpected RecT type");
+ return false;
+ }
+}
//-------------------------------------------------------------------------
//
@@ -122,7 +139,7 @@ config_update_thr(void *data)
{
REC_NOWARN_UNUSED(data);
while (true) {
- RecExecConfigUpdateCbs();
+ RecExecConfigUpdateCbs(REC_LOCAL_UPDATE_REQUIRED);
usleep(REC_CONFIG_UPDATE_INTERVAL_MS * 1000);
}
return NULL;
@@ -170,7 +187,7 @@ RecLocalInitMessage()
return REC_ERR_OKAY;
}
- if (RecMessageInit(RECM_SERVER) == REC_ERR_FAIL) {
+ if (RecMessageInit() == REC_ERR_FAIL) {
return REC_ERR_FAIL;
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/RecMessage.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecMessage.cc b/lib/records/RecMessage.cc
index fc80dda..a9135ac 100644
--- a/lib/records/RecMessage.cc
+++ b/lib/records/RecMessage.cc
@@ -31,7 +31,6 @@
static bool g_message_initialized = false;
static RecMessageRecvCb g_recv_cb = NULL;
static void *g_recv_cookie = NULL;
-static RecModeT g_mode_type;
//-------------------------------------------------------------------------
//
@@ -130,7 +129,7 @@ recv_cb_thr(void *data)
//-------------------------------------------------------------------------
int
-RecMessageInit(RecModeT mode_type)
+RecMessageInit()
{
RecHandle h_pipe;
@@ -139,7 +138,11 @@ RecMessageInit(RecModeT mode_type)
return REC_ERR_OKAY;
}
- g_mode_type = mode_type;
+ /*
+ * g_mode_type should be initialized by
+ * RecLocalInit() or RecProcessInit() earlier.
+ */
+ ink_assert(g_mode_type != RECM_NULL);
g_send_llq = create_queue();
g_recv_llq = create_queue();
@@ -215,12 +218,18 @@ RecMessageSend(RecMessage * msg)
//-------------------------------------------------------------------------
int
-RecMessageInit(RecModeT mode_type)
+RecMessageInit()
{
if (g_message_initialized) {
return REC_ERR_OKAY;
}
- g_mode_type = mode_type;
+
+ /*
+ * g_mode_type should be initialized by
+ * RecLocalInit() or RecProcessInit() earlier.
+ */
+ ink_assert(g_mode_type != RECM_NULL);
+
#if defined (LOCAL_MANAGER)
lmgmt->registerMgmtCallback(MGMT_SIGNAL_LIBRECORDS, RecMessageRecvThis, NULL);
#elif defined(PROCESS_MANAGER)
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3321de50/lib/records/RecProcess.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecProcess.cc b/lib/records/RecProcess.cc
index b27fb93..f43a834 100644
--- a/lib/records/RecProcess.cc
+++ b/lib/records/RecProcess.cc
@@ -28,6 +28,7 @@
#include "P_RecProcess.h"
#include "P_RecMessage.h"
#include "P_RecUtils.h"
+#include "P_RecCompatibility.h"
#include "mgmtapi.h"
@@ -36,14 +37,47 @@ static bool g_message_initialized = false;
static bool g_started = false;
static ink_cond g_force_req_cond;
static ink_mutex g_force_req_mutex;
-static RecModeT g_mode_type = RECM_NULL;
static int g_rec_raw_stat_sync_interval_ms = REC_RAW_STAT_SYNC_INTERVAL_MS;
static int g_rec_config_update_interval_ms = REC_CONFIG_UPDATE_INTERVAL_MS;
static int g_rec_remote_sync_interval_ms = REC_REMOTE_SYNC_INTERVAL_MS;
-#define REC_PROCESS
-#include "P_RecCore.i"
-#undef REC_PROCESS
+//-------------------------------------------------------------------------
+// i_am_the_record_owner, only used for librecprocess.a
+//-------------------------------------------------------------------------
+bool
+i_am_the_record_owner(RecT rec_type)
+{
+ if (g_mode_type == RECM_CLIENT) {
+ switch (rec_type) {
+ case RECT_PROCESS:
+ case RECT_PLUGIN:
+ return true;
+ case RECT_CONFIG:
+ case RECT_NODE:
+ case RECT_CLUSTER:
+ case RECT_LOCAL:
+ return false;
+ default:
+ ink_debug_assert(!"Unexpected RecT type");
+ return false;
+ }
+ } else if (g_mode_type == RECM_STAND_ALONE) {
+ switch (rec_type) {
+ case RECT_CONFIG:
+ case RECT_PROCESS:
+ case RECT_NODE:
+ case RECT_CLUSTER:
+ case RECT_LOCAL:
+ case RECT_PLUGIN:
+ return true;
+ default:
+ ink_debug_assert(!"Unexpected RecT type");
+ return false;
+ }
+ }
+
+ return false;
+}
//-------------------------------------------------------------------------
// Simple setters for the intervals to decouple this from the proxy
@@ -245,7 +279,7 @@ struct config_update_cont: public Continuation
REC_NOWARN_UNUSED(event);
REC_NOWARN_UNUSED(e);
while (true) {
- RecExecConfigUpdateCbs();
+ RecExecConfigUpdateCbs(REC_PROCESS_UPDATE_REQUIRED);
Debug("statsproc", "config_update_cont() processed");
usleep(g_rec_config_update_interval_ms * 1000);
}
@@ -349,7 +383,7 @@ RecProcessInitMessage(RecModeT mode_type)
return REC_ERR_OKAY;
}
- if (RecMessageInit(mode_type) == REC_ERR_FAIL) {
+ if (RecMessageInit() == REC_ERR_FAIL) {
return REC_ERR_FAIL;
}