Here's some code I've written for an MMO server I'm working on. I'd love some opinions and eventually unspotted bugs.
struct Data { Data(int i) :id(i) {} int id; };
class list
{
public:
struct Node { std::shared_ptr<Data> d_; std::shared_ptr<Node> next; };
private:
CRITICAL_SECTION update_lock;
concurrency::concurrent_queue<std::shared_ptr<Data>> to_add;
concurrency::concurrent_queue<int> to_remove;
std::shared_ptr<Node> head;
std::atomic_uint32_t count;
void push_back(std::shared_ptr<Data> d) {
std::shared_ptr<Node> n = std::make_shared<Node>();
n->d_ = std::move(d);
n->next = head;
while (!std::atomic_compare_exchange_weak(&head, &head, n)) {}
count++;
}
void remove(int id) {
std::shared_ptr<Node> t_0 = nullptr;
std::shared_ptr<Node> t_1 = head;
while (1)
{
if (!t_1) break;
if (t_1->d_->id == id)
{
if (!t_0) { while (1) { if (std::atomic_compare_exchange_weak(&head, &head, head->next))break; } }
else { while (1) { if (std::atomic_compare_exchange_weak(&t_0->next, &t_0->next, t_1->next))break; } }
t_1 = nullptr;
count--;
break;
}
t_0 = t_1;
t_1 = t_1->next;
}
}
public:
list() : head(nullptr) { InitializeCriticalSection(&update_lock); }
~list() {
//clear the list
while (head)
{
head = head->next;
}
DeleteCriticalSection(&update_lock);
}
uint32_t get_count() { return count.load(std::memory_order_relaxed); }
void add_remove(std::shared_ptr<Data> d, bool add) {
if (add) to_add.push(std::move(d)); else to_remove.push(d->id);
unsigned char t_c = 0;
/*IMPORTANT-TO-GET: no. of instructions it takes for the function to exit the while_loop and leave the critical_section*/
unsigned char n = 10;
while (1) {
if (++t_c > n) return;
if (TryEnterCriticalSection(&update_lock)) break;
}
std::shared_ptr<Data> temp = nullptr;
while (1)
{
if (!to_add.try_pop(temp)) break;
push_back(temp);
}
int temp_id;
while (1)
{
if (!to_remove.try_pop(temp_id)) break;
remove(temp_id);
}
LeaveCriticalSection(&update_lock);
}
};
#includes
- including whichever non-standard ones defineCRITICAL_SECTION
,InitializeCriticalSection
andDeleteCriticalSection
. Please add the includes and mention which library needs to be installed for the non-standard ones. It would also help if you showed the test code, too. \$\endgroup\$std::atomic_compare_exchange_weak(&head, &head, n)
. It makes no sense to pass the same pointer as atomic object and expected content. \$\endgroup\$