So that we can just move the pointers instead of copying data.
This means less mutex contention in state.c
VALUE_PAIR *config; //!< #VALUE_PAIR (s) used to set per request parameters
//!< for modules and the server core at runtime.
+
+ TALLOC_CTX *state_ctx; //!< for request->state
VALUE_PAIR *state; //!< #VALUE_PAIR (s) available over the lifetime of the authentication
//!< attempt. Useful where the attempt involves a sequence of
//!< many request/challenge packets, like OTP, and EAP.
int tries;
- VALUE_PAIR *vps;
+ TALLOC_CTX *ctx;
+ VALUE_PAIR *vps;
void *opaque;
void (*free_opaque)(void *opaque);
(void) talloc_get_type_abort(entry, state_entry_t);
#endif
rbtree_deletebydata(state->tree, entry);
+
+ if (entry->ctx) talloc_free(entry->ctx);
+
talloc_free(entry);
}
* Unused. We can delete it, even if now isn't
* the time to clean it up.
*/
- if (!entry->vps && !entry->opaque) {
+ if (!entry->ctx && !entry->opaque) {
state_entry_free(state, entry);
continue;
}
if (old) {
entry->tries = old->tries + 1;
- rad_assert(old->vps == NULL);
-
/*
* Track State
*/
{
state_entry_t *entry;
fr_state_t *state = &global_state;
+ TALLOC_CTX *old_ctx = NULL;
rad_assert(request->state == NULL);
* isn't thread-safe.
*/
if (entry) {
- fr_pair_list_mcopy_by_num(request, &request->state, &entry->vps, 0, 0, TAG_ANY);
- RDEBUG2("session-state: Found cached attributes");
- rdebug_pair_list(L_DBG_LVL_1, request, request->state, NULL);
+ RDEBUG2("Restoring &session-state");
+
+ if (request->state_ctx) old_ctx = request->state_ctx;
+
+ request->state_ctx = entry->ctx;
+ request->state = entry->vps;
+
+ entry->ctx = NULL;
+ entry->vps = NULL;
+
+ rdebug_pair_list(L_DBG_LVL_2, request, request->state, "&session-state:");
} else {
RDEBUG2("session-state: No cached attributes");
PTHREAD_MUTEX_UNLOCK(&state->mutex);
+ /*
+ * Free this outside of the mutex for less contention.
+ */
+ if (old_ctx) talloc_free(old_ctx);
+
VERIFY_REQUEST(request);
return;
}
return false;
}
- /*
- * This has to be done in a mutex lock, because talloc
- * isn't thread-safe.
- */
- fr_pair_list_mcopy_by_num(entry, &entry->vps, &request->state, 0, 0, TAG_ANY);
+ rad_assert(entry->ctx == NULL);
+ entry->ctx = request->state_ctx;
+ entry->vps = request->state;
+
+ request->state_ctx = NULL;
+ request->state = NULL;
+
PTHREAD_MUTEX_UNLOCK(&state->mutex);
rad_assert(request->state == NULL);
return request;
case PAIR_LIST_STATE:
- return request;
+ return request->state_ctx;
#ifdef WITH_PROXY
case PAIR_LIST_PROXY_REQUEST:
request->home_server = NULL;
#endif
+ /*
+ * This is parented separately.
+ */
+ if (request->state_ctx) {
+ talloc_free(request->state_ctx);
+ }
+
return 0;
}
request->component = "<core>";
request->log.func = vradlog_request;
+ request->state_ctx = talloc_init("session-state");
+
return request;
}
#ifdef WITH_VERIFY_PTR
fr_pair_list_verify(file, line, request, request->config);
- fr_pair_list_verify(file, line, request, request->state);
+ fr_pair_list_verify(file, line, request->state_ctx, request->state);
#endif
if (request->packet) verify_packet(file, line, request, request->packet, "request");
if (c->state) {
rdebug_pair_list(L_DBG_LVL_2, request, c->state, "&session-state:");
- radius_pairmove(request, &request->state, fr_pair_list_copy(request->state, c->state), false);
+
+ fr_pair_list_mcopy_by_num(request->state_ctx, &request->state, &c->state, 0, 0, TAG_ANY);
}
if (inst->stats) {
perl_store_vps(request->reply, request, &request->reply->vps, rad_reply_hv, "RAD_REPLY", "reply");
perl_store_vps(request, request, &request->config, rad_check_hv, "RAD_CHECK", "control");
perl_store_vps(request, request, &request->config, rad_config_hv, "RAD_CONFIG", "control");
- perl_store_vps(request, request, &request->state, rad_state_hv, "RAD_STATE", "session-state");
+ perl_store_vps(request->state_ctx, request, &request->state, rad_state_hv, "RAD_STATE", "session-state");
#ifdef WITH_PROXY
rad_request_proxy_hv = get_hv("RAD_REQUEST_PROXY",1);
vp = NULL;
}
- if ((get_hv_content(request, request, rad_state_hv, &vp, "RAD_STATE", "session-state")) == 0) {
+ if ((get_hv_content(request->state_ctx, request, rad_state_hv, &vp, "RAD_STATE", "session-state")) == 0) {
fr_pair_list_free(&request->state);
request->state = vp;
vp = NULL;