Skip to content

dispatcher script only runs once on osx because shared memory regions can only be resized once. #786

@TomHodson

Description

@TomHodson

Observed behaviour

Running the dispatcher script on OSX only succeeds once and after that fails with error "Dispatcher_Server::2".

What I think causes it
In this code in src/template_db/dispatcher:

#ifdef __APPLE__
dispatcher_shm_fd = shm_open
(dispatcher_share_name.c_str(), O_RDWR|O_CREAT, S_666);
if (dispatcher_shm_fd < 0)
throw File_Error(errno, dispatcher_share_name, "Dispatcher_Server::APPLE::1");
#else
dispatcher_shm_fd = shm_open
(dispatcher_share_name.c_str(), O_RDWR|O_CREAT|O_TRUNC|O_EXCL, S_666);
if (dispatcher_shm_fd < 0)
throw File_Error(errno, dispatcher_share_name, "Dispatcher_Server::1");
fchmod(dispatcher_shm_fd, S_666);
#endif
std::string db_dir = transaction_insulator.db_dir();
{
int foo = ftruncate(
dispatcher_shm_fd, SHM_SIZE + db_dir.size() + shadow_name.size());
if (foo)
throw File_Error(errno, dispatcher_share_name, "Dispatcher_Server::2");
}

A shared memory object file descriptor dispatcher_shm_fd is created and then later ftruncate is called on it to resize it. If that call fails we throw the error Dispatcher_Server::2.

I found a stack overflow question explaining the fact that on OSX ftruncate only works once on the initial creation of the shared memory object and fails thereafter. I think this explains the observed behaviour. The suggestion in that post is to use fstat to check the size of the shared memory object.

I would propose adding an fstat check that runs the ftruncate if st_size is 0 and errors out if the shared memory object has already been resized to something different from the desired size. This behaviour could be gated behind an #ifdef __APPLE__ if you prefer hiding the addition complexity from other platforms.

Let me know if you would consider adding this and I'll put in a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions