SysCallbacks.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "SysCallbacks.h"
  2. #include "syscb/ifc_syscallback.h"
  3. using namespace nu;
  4. SysCallbacks::SysCallbacks()
  5. {
  6. reentry=0;
  7. inCallback=false;
  8. }
  9. //note: it's OK to add in the middle of an issueCallback
  10. //because new callbacks go at the end of the list
  11. //and the lockguard prevents list corruption
  12. int SysCallbacks::SysCallbacks_RegisterCallback(ifc_sysCallback *cb)
  13. {
  14. AutoLock lock(callbackGuard LOCKNAME("SysCallbacks::syscb_registerCallback"));
  15. callbacks.push_back(cb);
  16. return 0;
  17. }
  18. int SysCallbacks::SysCallbacks_UnregisterCallback(ifc_sysCallback *cb)
  19. {
  20. AutoLock lock(callbackGuard LOCKNAME("SysCallbacks::syscb_deregisterCallback"));
  21. if (inCallback)
  22. deleteMeAfterCallbacks.push_back(cb);
  23. else
  24. {
  25. //callbacks.eraseAll(cb);
  26. auto it = callbacks.begin();
  27. while (it != callbacks.end())
  28. {
  29. if (*it != cb)
  30. {
  31. it++;
  32. continue;
  33. }
  34. it = callbacks.erase(it);
  35. }
  36. }
  37. return 0;
  38. }
  39. int SysCallbacks::SysCallbacks_IssueCallback( GUID eventtype, int msg, intptr_t param1, intptr_t param2 )
  40. {
  41. AutoLock lock( callbackGuard LOCKNAME( "SysCallbacks::syscb_issueCallback" ) );
  42. reentry++;
  43. inCallback = true;
  44. for ( ifc_sysCallback *l_call_back : callbacks )
  45. {
  46. //if (!deleteMeAfterCallbacks.contains(callbacks[i]) && callbacks[i]->GetEventType() == eventtype)
  47. if ( deleteMeAfterCallbacks.end() == std::find( deleteMeAfterCallbacks.begin(), deleteMeAfterCallbacks.end(), l_call_back ) && l_call_back->GetEventType() == eventtype )
  48. l_call_back->Notify( msg, param1, param2 );
  49. }
  50. inCallback = false;
  51. reentry--;
  52. if ( reentry == 0 )
  53. {
  54. for ( ifc_sysCallback *l_delete_me_after_call_back : deleteMeAfterCallbacks )
  55. {
  56. //callbacks.eraseAll(deleteMeAfterCallbacks[i]);
  57. auto it = callbacks.begin();
  58. while ( it != callbacks.end() )
  59. {
  60. if ( *it != l_delete_me_after_call_back )
  61. {
  62. it++;
  63. continue;
  64. }
  65. it = callbacks.erase( it );
  66. }
  67. }
  68. deleteMeAfterCallbacks.clear();
  69. }
  70. return 0;
  71. }
  72. ifc_sysCallback *SysCallbacks::SysCallbacks_Enum( GUID eventtype, size_t n )
  73. {
  74. AutoLock lock( callbackGuard LOCKNAME( "SysCallbacks::syscb_enum" ) );
  75. // TODO: maybe check !deleteMeAfterCallbacks.contains(callbacks[i])
  76. for ( ifc_sysCallback *callback : callbacks )
  77. {
  78. if ( callback->GetEventType() == eventtype )
  79. {
  80. if ( n-- == 0 )
  81. {
  82. // benski> don't be fooled. most objects don't actually support reference counting
  83. callback->Retain();
  84. return callback;
  85. }
  86. }
  87. }
  88. return 0;
  89. }