Skip to content

Commit

Permalink
Replace deprecated readdir_r.
Browse files Browse the repository at this point in the history
Calls to readdir(3) are not guaranteed to be thread safe so we introduce a
spinlock around calls. This synchronization will usually not be necessary, but
we have to ensure correctness.
brixen committed Aug 16, 2016
1 parent d72df4a commit b805d80
Showing 2 changed files with 13 additions and 5 deletions.
15 changes: 10 additions & 5 deletions machine/builtin/dir.cpp
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@
#include "builtin/string.hpp"

namespace rubinius {
rubinius::locks::spinlock_mutex Dir::readdir_lock_;

void Dir::bootstrap(STATE) {
GO(dir).set(state->memory()->new_class<Class, Dir>(state, "Dir"));
}
@@ -86,16 +88,19 @@ namespace rubinius {
Object* Dir::read(STATE) {
guard(state);

struct dirent ent;
struct dirent* entp = &ent;
if(int erno = readdir_r(os(), entp, &entp)) {
Exception::raise_errno_error(state, "readdir_r(3) failed", erno);
struct dirent* entp = nullptr;

{
std::lock_guard<locks::spinlock_mutex> guard(readdir_lock_);

entp = readdir(os());
}

if(!entp) return cNil;

String* str = String::create(state, ent.d_name);
String* str = String::create(state, entp->d_name);
str->encoding(state, encoding());

return str;
}

3 changes: 3 additions & 0 deletions machine/builtin/dir.hpp
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
#define RBX_BUILTIN_DIR_HPP

#include "object_utils.hpp"
#include "spinlock.hpp"

#include "builtin/encoding.hpp"
#include "builtin/object.hpp"
@@ -14,6 +15,8 @@ namespace rubinius {
class Encoding;

class Dir : public Object {
static rubinius::locks::spinlock_mutex readdir_lock_;

public:
const static object_type type = DirType;

0 comments on commit b805d80

Please sign in to comment.