LockFreeItem.h 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #pragma once
  2. #include <windows.h>
  3. /* This data structure holds one item, and returns you the old item when you replace it
  4. it's sort of a "stack of 1" */
  5. template <class value_t>
  6. class LockFreeItem
  7. {
  8. public:
  9. typedef value_t *ptr_t;
  10. LockFreeItem() { item = 0; }
  11. value_t *GetItem()
  12. {
  13. for(;;) // keep trying until we get this right
  14. {
  15. volatile ptr_t ret;
  16. InterlockedExchangePointer(&ret, item);
  17. if (InterlockedCompareExchangePointer((volatile PVOID *)&item, 0, ret) == ret)
  18. return ret;
  19. }
  20. }
  21. // returns the previous value
  22. value_t *SetItem(value_t *new_item)
  23. {
  24. for(;;) // keep trying until we get this right
  25. {
  26. volatile ptr_t ret;
  27. InterlockedExchangePointer(&ret, item);
  28. if (InterlockedCompareExchangePointer((volatile PVOID *)&item, new_item, ret) == ret)
  29. return ret;
  30. }
  31. }
  32. // if there's already a value, returns what you passed in
  33. value_t *SetItemIfZero(value_t *new_item)
  34. {
  35. if (InterlockedCompareExchangePointer((volatile PVOID *)&item, new_item, 0) == 0)
  36. return 0;
  37. else
  38. return new_item;
  39. }
  40. volatile ptr_t item;
  41. };