Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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