PERFORCE change 110291 for review
Michael Bushkov
bushman at FreeBSD.org
Tue Nov 21 16:20:32 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=110291
Change 110291 by bushman at bushman_nss_ldap_cached on 2006/11/20 11:09:09
+ Now, before writing something to cache, we check for such element existence.
With this check we now avoid some race-condition situations, when 2 program
write similar data to the same cache entry.
Affected files ...
.. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#10 edit
Differences ...
==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#10 (text) ====
@@ -339,6 +339,7 @@
struct cache_write_request *write_request;
struct cache_write_response *write_response;
cache_entry c_entry;
+ size_t tdata_size;
TRACE_IN(on_write_request_process);
init_comm_element(&qstate->response, CET_WRITE_RESPONSE);
@@ -386,19 +387,35 @@
if (c_entry != NULL) {
configuration_lock_entry(qstate->config_entry, CELT_POSITIVE);
qstate->config_entry->positive_cache_entry = c_entry;
- write_response->error_code = cache_write(c_entry,
+
+ /* checking if there is already a record in the cache */
+ write_response->error_code = cache_read(c_entry,
write_request->cache_key,
- write_request->cache_key_size,
- write_request->data,
- write_request->data_size);
- configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE);
+ write_request->cache_key_size, NULL,
+ &tdata_size);
+
+ if (write_response->error_code == -1) {
+ write_response->error_code = cache_write(c_entry,
+ write_request->cache_key, write_request->cache_key_size,
+ write_request->data, write_request->data_size);
- if ((qstate->config_entry->common_query_timeout.tv_sec != 0) ||
- (qstate->config_entry->common_query_timeout.tv_usec != 0))
+ if ((qstate->config_entry->common_query_timeout.tv_sec
+ != 0) ||
+ (qstate->config_entry->common_query_timeout.tv_usec
+ != 0))
memcpy(&qstate->timeout,
- &qstate->config_entry->common_query_timeout,
- sizeof(struct timeval));
-
+ &qstate->config_entry->common_query_timeout,
+ sizeof(struct timeval));
+ } else {
+ LOG_ERR_2("write_request",
+ "trying to write to entry '%s', despite that "
+ "there is already an element with specified "
+ "key in the cache", write_request->entry);
+
+ write_response->error_code = -1;
+ }
+
+ configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE);
} else
write_response->error_code = -1;
@@ -417,6 +434,7 @@
struct cache_write_request *write_request;
struct cache_write_response *write_response;
cache_entry c_entry;
+ size_t tdata_size;
TRACE_IN(on_negative_write_request_process);
init_comm_element(&qstate->response, CET_WRITE_RESPONSE);
@@ -468,20 +486,37 @@
if (c_entry != NULL) {
configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE);
qstate->config_entry->negative_cache_entry = c_entry;
- write_response->error_code = cache_write(c_entry,
+
+ write_response->error_code = cache_read(c_entry,
write_request->cache_key,
- write_request->cache_key_size,
- negative_data,
- sizeof(negative_data));
+ write_request->cache_key_size,
+ NULL,
+ &tdata_size);
+ if (write_response->error_code == -1) {
+ write_response->error_code = cache_write(c_entry,
+ write_request->cache_key, write_request->cache_key_size,
+ negative_data, sizeof(negative_data));
+
+ if ((qstate->config_entry->common_query_timeout.tv_sec
+ != 0) ||
+ (qstate->config_entry->common_query_timeout.tv_usec
+ != 0))
+ memcpy(&qstate->timeout,
+ &qstate->config_entry->common_query_timeout,
+ sizeof(struct timeval));
+ } else
+ write_response->error_code = -1;
+
configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE);
-
- if ((qstate->config_entry->common_query_timeout.tv_sec != 0) ||
- (qstate->config_entry->common_query_timeout.tv_usec != 0))
- memcpy(&qstate->timeout,
- &qstate->config_entry->common_query_timeout,
- sizeof(struct timeval));
- } else
+ } else {
+ LOG_ERR_2("write_request",
+ "trying to write negative request to entry "
+ "'%s', despite that "
+ "there is already an element with specified "
+ "key in the cache", write_request->entry);
+
write_response->error_code = -1;
+ }
fin:
qstate->kevent_filter = EVFILT_WRITE;
@@ -697,9 +732,11 @@
}
configuration_unlock_entry(qstate->config_entry, CELT_POSITIVE);
- configuration_lock_entry(qstate->config_entry, CELT_NEGATIVE);
- qstate->config_entry->negative_cache_entry = neg_c_entry;
if (read_response->error_code == -1) {
+ configuration_lock_entry(qstate->config_entry,
+ CELT_NEGATIVE);
+ qstate->config_entry->negative_cache_entry =
+ neg_c_entry;
read_response->error_code = cache_read(neg_c_entry,
read_request->cache_key,
read_request->cache_key_size, NULL,
@@ -710,8 +747,9 @@
read_response->data = NULL;
read_response->data_size = 0;
}
- }
- configuration_unlock_entry(qstate->config_entry, CELT_NEGATIVE);
+ configuration_unlock_entry(qstate->config_entry,
+ CELT_NEGATIVE);
+ }
if ((read_response->error_code == -1) &&
(qstate->config_entry->flags &
More information about the p4-projects
mailing list