Skip to content

Commit

Permalink
SWDEV-400644: Reset the mutex only if errors
Browse files Browse the repository at this point in the history
To prevent reset the mutex while using it, only reset the mutex
if it cannot acquire it.

Change-Id: I95e0ed1bf543f285ce81b4df9c51e16a88081d38
  • Loading branch information
bill-shuzhou-liu authored and dmitrii-galantsev committed May 25, 2023
1 parent cdfc340 commit c556c60
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
25 changes: 15 additions & 10 deletions third_party/shared_mutex/shared_mutex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static std::vector<std::string> lsof(const char* filename) {
return matched_process;
}

shared_mutex_t shared_mutex_init(const char *name, mode_t mode) {
shared_mutex_t shared_mutex_init(const char *name, mode_t mode, bool retried) {
shared_mutex_t mutex = {NULL, 0, NULL, 0};
errno = 0;

Expand Down Expand Up @@ -123,15 +123,6 @@ shared_mutex_t shared_mutex_init(const char *name, mode_t mode) {

pthread_mutex_t *mutex_ptr = reinterpret_cast<pthread_mutex_t *>(addr);

// When process crash before unlock the mutex, the mutex is in bad status.
// reset the mutex if no process is using it
std::vector<std::string> ids = lsof(name);
if (ids.size() == 0) { // no process is using it
memset(mutex_ptr, 0, sizeof(pthread_mutex_t));
// Set mutex.created == 1 so that it can be initialized latter.
mutex.created = 1;
}

// Make sure the mutex wasn't left in a locked state. If we can't
// acquire it in 5 sec., re-do everything.
struct timespec expireTime;
Expand Down Expand Up @@ -161,6 +152,20 @@ shared_mutex_t shared_mutex_init(const char *name, mode_t mode) {
} else if (ret || (mutex.created == 0 &&
reinterpret_cast<shared_mutex_t *>(addr)->ptr == NULL)) {
// Something is out of sync.

// When process crash before unlock the mutex, the mutex is in bad status.
// reset the mutex if no process is using it, and then retry lock
if (!retried) {
std::vector<std::string> ids = lsof(name);
if (ids.size() == 0) { // no process is using it
memset(mutex_ptr, 0, sizeof(pthread_mutex_t));
// Set mutex.created == 1 so that it can be initialized latter.
mutex.created = 1;
free(mutex.name);
return shared_mutex_init(name, mode, true);
}
}

fprintf(stderr, "pthread_mutex_timedlock() returned %d\n", ret);
perror("Failed to initialize RSMI device mutex after 5 seconds. Previous "
"execution may not have shutdown cleanly. To fix problem, stop all "
Expand Down
2 changes: 1 addition & 1 deletion third_party/shared_mutex/shared_mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef struct shared_mutex_t {
// There is no workaround currently, except to run first
// initialization only before multi-threaded or multi-process
// functionality.
shared_mutex_t shared_mutex_init(const char *name, mode_t mode);
shared_mutex_t shared_mutex_init(const char *name, mode_t mode, bool retried=false);

// Close access to the shared mutex and free all the resources,
// used by the structure.
Expand Down

0 comments on commit c556c60

Please sign in to comment.