I was wondering how the memcached source code is multithread safe in a multicore enviornement, when the manipulation of many of the _stritem or item structs variables don't seem to utilize a lock when manipulated (instead using refcount to indicate how many threads are using the item).
Line: 519 in memcached.h
typedef struct _stritem {
/* Protected by LRU locks */
struct _stritem *next;
struct _stritem *prev;
/* Rest are protected by an item lock */
struct _stritem *h_next; /* hash chain next */
rel_time_t time; /* least recent access */
rel_time_t exptime; /* expire time */
int nbytes; /* size of data */
unsigned short refcount;
uint16_t it_flags; /* ITEM_* above */
uint8_t slabs_clsid;/* which slab class we're in */
uint8_t nkey; /* key length, w/terminating null and padding */
/* this odd type prevents type-punning issues when we do
* the little shuffle to save space when not using CAS. */
union {
uint64_t cas;
char end;
} data[];
/* if it_flags & ITEM_CAS we have 8 bytes CAS */
/* then null-terminated key */
/* then " flags length\r\n" (no terminating null) */
/* then data with terminating \r\n (no terminating null; it's binary!) */
} item;
Line 851 in memcached.h
#define refcount_incr(it) ++(it->refcount)
#define refcount_decr(it) --(it->refcount)
Wouldn't a lack of locking on the item locks when incrementing/decrementing the variable structure in a multithreaded multicore environment potentially create a race condition?
For example: the variable could be fetched by both threads and placed in separate registers, then incremented in both registered, then replaced back in their memory location. This would cause a increment of only 1. Then if 1 thread decremented, couldn't the object be freed and then cause a problem for the other thread?
Edit: To clarify, given memcached has existed for 17 + years the implementation is most likely bug-free, but I am curious as to how memcached handles this.