Code analysis violations Bug in scheduler - race during with worker thread shutdown.
Showing the changes to src/vm/list.cpp (1 of 18 files). Show all
Unified · Split
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | // | 5 | // |
| 6 | 6 | ||
| 7 | #include <runtime.h> | 7 | #include <runtime.h> |
| 8 | #include <exceptions.h> | ||
| 8 | #include <vm_memory.h> | 9 | #include <vm_memory.h> |
| 9 | #include <debug.h> | 10 | #include <debug.h> |
| 10 | 11 | ||
| @@ -21,14 +22,10 @@ vm_list_t::vm_list_t(std::shared_ptr<const type_descriptor_t> td, vm_list_t *tai · 10 unmodified lines | |||
| 21 | , _element_type{ td } | 22 | , _element_type{ td } |
| 22 | , _is_alloc{ sizeof(_mem) < td->size_in_bytes } | 23 | , _is_alloc{ sizeof(_mem) < td->size_in_bytes } |
| 23 | , _mem{} | 24 | , _mem{} |
| 24 | , _tail{ tail } | 25 | , _tail{ nullptr } |
| 25 | { | 26 | { |
| 26 | assert(_element_type != nullptr); | 27 | assert(_element_type != nullptr); |
| 27 | if (_tail != nullptr) | 28 | set_tail(tail); |
| 28 | { | ||
| 29 | assert(tail->get_element_type() == _element_type); | ||
| 30 | _tail->add_ref(); | ||
| 31 | } | ||
| 32 | 29 | ||
| 33 | // If the default list element storage is not enough, allocate more memory. | 30 | // If the default list element storage is not enough, allocate more memory. |
| 34 | if (_is_alloc) | 31 | if (_is_alloc) |
| @@ -41,14 +38,15 @@ vm_list_t::vm_list_t(std::shared_ptr<const type_descriptor_t> td, vm_list_t *tai · 6 unmodified lines | |||
| 41 | init_memory(*_element_type, &_mem.local); | 38 | init_memory(*_element_type, &_mem.local); |
| 42 | } | 39 | } |
| 43 | 40 | ||
| 44 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm list: new\n"); | 41 | if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>()) |
| 42 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: vm list\n"); | ||
| 45 | } | 43 | } |
| 46 | 44 | ||
| 47 | vm_list_t::~vm_list_t() | 45 | vm_list_t::~vm_list_t() |
| 48 | { | 46 | { |
| 49 | // Remove tail | 47 | // Remove tail |
| 50 | dec_ref_count_and_free(_tail); | 48 | dec_ref_count_and_free(_tail); |
| 51 | _tail = nullptr; | 49 | debug::assign_debug_pointer(&_tail); |
| 52 | 50 | ||
| 53 | // Destroy and free the list element, if default element size was surpassed. | 51 | // Destroy and free the list element, if default element size was surpassed. |
| 54 | if (_is_alloc) | 52 | if (_is_alloc) |
| @@ -88,12 +86,20 @@ vm_list_t *vm_list_t::get_tail() const · 33 unmodified lines | |||
| 88 | return _tail; | 86 | return _tail; |
| 89 | } | 87 | } |
| 90 | 88 | ||
| 91 | vm_list_t *vm_list_t::drop_tail() | 89 | void vm_list_t::set_tail(vm_list_t *new_tail) |
| 92 | { | 90 | { |
| 93 | auto tail = _tail; | 91 | if (new_tail != nullptr) |
| 94 | _tail = nullptr; | 92 | { |
| 95 | tail->release(); | 93 | if (new_tail->get_element_type() != _element_type) |
| 96 | return tail; | 94 | throw type_violation{}; |
| 95 | |||
| 96 | new_tail->add_ref(); | ||
| 97 | } | ||
| 98 | |||
| 99 | auto prev_tail = _tail; | ||
| 100 | _tail = new_tail; | ||
| 101 | |||
| 102 | dec_ref_count_and_free(prev_tail); | ||
| 97 | } | 103 | } |
| 98 | 104 | ||
| 99 | pointer_t vm_list_t::value() const | 105 | pointer_t vm_list_t::value() const |