Skip to content

Commit f6bcd95

Browse files
committed
renderer: Fix lock of resource reads in render entity.
1 parent 66098ce commit f6bcd95

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

libopenage/renderer/stages/world/object.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ void WorldObject::fetch_updates(const time::time_t &time) {
6363

6464
// Get data from render entity
6565
this->ref_id = this->render_entity->get_id();
66+
67+
// Thread-safe access to curves needs a lock on the render entity's mutex
68+
auto read_lock = this->render_entity->get_read_lock();
6669
this->position.sync(this->render_entity->get_position());
6770
this->animation_info.sync(this->render_entity->get_animation_path(),
6871
std::function<std::shared_ptr<renderer::resources::Animation2dInfo>(const std::string &)>(
@@ -79,6 +82,9 @@ void WorldObject::fetch_updates(const time::time_t &time) {
7982
this->last_update);
8083
this->angle.sync(this->render_entity->get_angle(), this->last_update);
8184

85+
// Unlock mutex of the render entity
86+
read_lock.unlock();
87+
8288
// Set self to changed so that world renderer can update the renderable
8389
this->changed = true;
8490
this->render_entity->clear_changed_flag();

libopenage/renderer/stages/world/render_entity.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2022-2023 the openage authors. See copying.md for legal info.
1+
// Copyright 2022-2024 the openage authors. See copying.md for legal info.
22

33
#include "render_entity.h"
44

@@ -96,4 +96,8 @@ void WorldRenderEntity::clear_changed_flag() {
9696
this->changed = false;
9797
}
9898

99+
std::shared_lock<std::shared_mutex> WorldRenderEntity::get_read_lock() {
100+
return std::shared_lock{this->mutex};
101+
}
102+
99103
} // namespace openage::renderer::world

libopenage/renderer/stages/world/render_entity.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <cstdint>
66
#include <list>
7+
#include <mutex>
78
#include <shared_mutex>
89
#include <string>
910

@@ -30,6 +31,8 @@ class WorldRenderEntity {
3031
/**
3132
* Update the render entity with information from the gamestate.
3233
*
34+
* Updating the render entity with this method is thread-safe.
35+
*
3336
* @param ref_id Game entity ID.
3437
* @param position Position of the game entity inside the game world.
3538
* @param angle Angle of the game entity inside the game world.
@@ -47,6 +50,8 @@ class WorldRenderEntity {
4750
*
4851
* Update the render entity with information from the gamestate.
4952
*
53+
* Updating the render entity with this method is thread-safe.
54+
*
5055
* @param ref_id Game entity ID.
5156
* @param position Position of the game entity inside the game world.
5257
* @param animation_path Path to the animation definition.
@@ -60,34 +65,47 @@ class WorldRenderEntity {
6065
/**
6166
* Get the ID of the corresponding game entity.
6267
*
68+
* Accessing the game entity ID is thread-safe.
69+
*
6370
* @return Game entity ID.
6471
*/
6572
uint32_t get_id();
6673

6774
/**
6875
* Get the position of the entity inside the game world.
6976
*
77+
* Accessing the position curve REQUIRES a read lock on the render entity
78+
* (using \p get_read_lock()) to ensure thread safety.
79+
*
7080
* @return Position curve of the entity.
7181
*/
7282
const curve::Continuous<coord::scene3> &get_position();
7383

7484
/**
7585
* Get the angle of the entity inside the game world.
7686
*
87+
* Accessing the angle curve REQUIRES a read lock on the render entity
88+
* (using \p get_read_lock()) to ensure thread safety.
89+
*
7790
* @return Angle curve of the entity.
7891
*/
7992
const curve::Segmented<coord::phys_angle_t> &get_angle();
8093

8194
/**
8295
* Get the animation definition path.
8396
*
97+
* Accessing the animation path curve requires a read lock on the render entity
98+
* (using \p get_read_lock()) to ensure thread safety.
99+
*
84100
* @return Path to the animation definition file.
85101
*/
86102
const curve::Discrete<std::string> &get_animation_path();
87103

88104
/**
89105
* Get the time of the last update.
90106
*
107+
* Accessing the update time is thread-safe.
108+
*
91109
* @return Time of last update.
92110
*/
93111
time::time_t get_update_time();
@@ -105,6 +123,15 @@ class WorldRenderEntity {
105123
*/
106124
void clear_changed_flag();
107125

126+
/**
127+
* Get a shared lock for thread-safe reading from the render entity.
128+
*
129+
* The caller is responsible for unlocking the mutex after reading.
130+
*
131+
* @return Lock for the render entity.
132+
*/
133+
std::shared_lock<std::shared_mutex> get_read_lock();
134+
108135
private:
109136
/**
110137
* Flag for determining if the render entity has been updated by the

0 commit comments

Comments
 (0)