Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

Commit

Permalink
Build on MacOS
Browse files Browse the repository at this point in the history
  • Loading branch information
rabits committed Apr 2, 2021
1 parent b71e303 commit 2d208a0
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 42 deletions.
12 changes: 9 additions & 3 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ raftinclude_HEADERS =

lib_LTLIBRARIES = libraft.la
libraft_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
libraft_la_LDFLAGS = -version-info 0:7:0
libraft_la_LDFLAGS = -version-info 0:7:0 -no-undefined
libraft_la_SOURCES = \
src/byte.c \
src/client.c \
Expand All @@ -33,10 +33,13 @@ libraft_la_SOURCES = \
src/snapshot.c \
src/start.c \
src/state.c \
src/syscall.c \
src/tick.c \
src/tracing.c

if LINUX
libraft_la_SOURCES += src/syscall.c
endif

bin_PROGRAMS =

check_PROGRAMS = \
Expand Down Expand Up @@ -154,7 +157,6 @@ libtest_la_SOURCES += \
test_unit_uv_SOURCES = \
src/err.c \
src/heap.c \
src/syscall.c \
src/tracing.c \
src/uv_fs.c \
src/uv_os.c \
Expand All @@ -166,6 +168,10 @@ test_unit_uv_LDFLAGS = $(UV_LIBS)
test_unit_uv_CFLAGS = $(AM_CFLAGS) -Wno-conversion
test_unit_uv_LDADD = libtest.la

if LINUX
test_unit_uv_SOURCES += src/syscall.c
endif

# The integration/uv test is not linked to libraft, but built
# directly against the libraft sources in order to test some
# non-visible, non-API functions.
Expand Down
30 changes: 30 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ AC_USE_SYSTEM_EXTENSIONS # Defines _GNU_SOURCE and similar

LT_INIT

AC_CANONICAL_HOST

build_linux=no
build_windows=no
build_mac=no

#Detect target OS
AS_CASE([$host_os],[linux*],[build_linux=yes])
AS_CASE([$host_os],[mingw*],[build_windows=yes])
AS_CASE([$host_os],[darwin*],[build_mac=yes])

AM_CONDITIONAL([LINUX], [test "x$build_linux" = "xyes"])
AM_CONDITIONAL([WINDOWS], [test "x$build_windows" = "xyes"])
AM_CONDITIONAL([MAC], [test "x$build_mac" = "xyes"])

# The libuv raft_io implementation is built by default if libuv is found, unless
# explicitly disabled.
AC_ARG_ENABLE(uv, AS_HELP_STRING([--disable-uv], [do not build the libuv-based raft_io implementation]))
Expand Down Expand Up @@ -125,5 +140,20 @@ CC_CHECK_FLAGS_APPEND([AM_LDFLAGS],[LDFLAGS],[ \
])
AC_SUBST(AM_LDLAGS)

CC_CHECK_FLAGS_APPEND([AM_LDFLAGS],[LDFLAGS],[ \
-z relro \
-z now \
-fstack-protector-strong \
--param=ssp-buffer-size=4 \
])
AC_SUBST(AM_LDLAGS)

case $host in
*mingw*)
# -D__USE_MINGW_ANSI_STDIO is deprecated it seems.
CC_CHECK_FLAGS_APPEND([AM_CFLAGS],[CFLAGS],[-D_POSIX])
;;
esac

AC_CONFIG_FILES([raft.pc Makefile])
AC_OUTPUT
11 changes: 11 additions & 0 deletions example/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
#define Logf(SERVER_ID, FORMAT, ...) \
printf("%d: " FORMAT "\n", SERVER_ID, __VA_ARGS__)

//apparently srandom isn't defined on mingw
#if !defined(srandom)
#define srandom srand
#endif

/********************************************************************
*
* Sample application FSM that just increases a counter.
Expand Down Expand Up @@ -166,8 +171,12 @@ static int ServerInit(struct Server *s,
memset(s, 0, sizeof *s);

/* Seed the random generator */
#if defined(_WIN32)
srandom((unsigned)time(NULL));
#else
timespec_get(&now, TIME_UTC);
srandom((unsigned)(now.tv_nsec ^ now.tv_sec));
#endif

s->loop = loop;

Expand Down Expand Up @@ -385,8 +394,10 @@ int main(int argc, char *argv[])
dir = argv[1];
id = (unsigned)atoi(argv[2]);

#if !defined(_WIN32)
/* Ignore SIGPIPE, see https://github.com/joyent/libuv/issues/1254 */
signal(SIGPIPE, SIG_IGN);
#endif

/* Initialize the libuv loop. */
rv = uv_loop_init(&loop);
Expand Down
2 changes: 1 addition & 1 deletion src/byte.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ A million repetitions of "a"
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/

#if defined(vax) || defined(ns32000) || defined(sun386) || \
defined(__i386__) || defined(MIPSEL) || defined(_MIPSEL) || \
defined(__i386__) || defined(__x86_64__) || defined(MIPSEL) || defined(_MIPSEL) || \
defined(BIT_ZERO_ON_RIGHT) || defined(__alpha__) || defined(__alpha)
#define BYTE_ORDER LITTLE_ENDIAN
#endif
Expand Down
14 changes: 8 additions & 6 deletions src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,15 @@ int raft_add(struct raft *r,

req->cb = cb;

assert(r->leader_state.change == NULL);
r->leader_state.change = req;

rv = clientChangeConfiguration(r, req, &configuration);
if (rv != 0) {
r->leader_state.change = NULL;
goto err_after_configuration_copy;
}

assert(r->leader_state.change == NULL);
r->leader_state.change = req;

return 0;

err_after_configuration_copy:
Expand Down Expand Up @@ -352,14 +353,15 @@ int raft_remove(struct raft *r,

req->cb = cb;

assert(r->leader_state.change == NULL);
r->leader_state.change = req;

rv = clientChangeConfiguration(r, req, &configuration);
if (rv != 0) {
r->leader_state.change = NULL;
goto err_after_configuration_copy;
}

assert(r->leader_state.change == NULL);
r->leader_state.change = req;

return 0;

err_after_configuration_copy:
Expand Down
21 changes: 21 additions & 0 deletions src/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,34 @@ static void *defaultRealloc(void *data, void *ptr, size_t size)
static void *defaultAlignedAlloc(void *data, size_t alignment, size_t size)
{
(void)data;
#ifdef _WIN32
return _aligned_malloc(size, alignment);
#elif defined(__APPLE__)
void * p1; // original block
void ** p2; // aligned block
size_t offset = alignment + sizeof(void *) - 1;
if ((p1 = (void *)malloc(size + offset)) == NULL)
return NULL;
p2 = (void **)(((uintptr_t)(p1) + offset) & ~(alignment - 1));
p2[-1] = p1;
return p2;
#else
return aligned_alloc(alignment, size);
#endif
}

static void defaultAlignedFree(void *data, size_t alignment, void *ptr)
{
(void)alignment;
#ifdef _WIN32
(void)ptr;
_aligned_free(data);
#elif defined(__APPLE__)
(void)data;
free(((void * *)ptr)[-1]);
#else
defaultFree(data, ptr);
#endif
}

static struct raft_heap defaultHeap = {
Expand Down
1 change: 1 addition & 0 deletions src/raft.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ int raft_bootstrap(struct raft *r, const struct raft_configuration *conf)

rv = r->io->bootstrap(r->io, conf);
if (rv != 0) {
ErrMsgTransfer(r->io->errmsg, r->errmsg, "io");
return rv;
}

Expand Down
2 changes: 2 additions & 0 deletions src/uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,14 @@ static int uvBootstrap(struct raft_io *io,
/* Write the term */
rv = uvSetTerm(io, 1);
if (rv != 0) {
ErrMsgPrintf(io->errmsg, "Unable to set UV term");
return rv;
}

/* Create the first closed segment file, containing just one entry. */
rv = uvSegmentCreateFirstClosed(uv, configuration);
if (rv != 0) {
ErrMsgPrintf(io->errmsg, "Unable to create first closed segment");
return rv;
}

Expand Down
46 changes: 45 additions & 1 deletion src/uv_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <sys/vfs.h>
#endif
#include <unistd.h>

#include "assert.h"
Expand Down Expand Up @@ -55,6 +57,10 @@ int UvFsCheckDir(const char *dir, char *errmsg)

int UvFsSyncDir(const char *dir, char *errmsg)
{
#ifdef _WIN32
// Windows doesn't really support sync on folders.
return 0;
#endif
uv_file fd;
int rv;
rv = UvOsOpen(dir, UV_FS_O_RDONLY | UV_FS_O_DIRECTORY, 0, &fd);
Expand Down Expand Up @@ -181,7 +187,9 @@ int UvFsAllocateFile(const char *dir,
UvOsJoin(dir, filename, path);

/* TODO: use RWF_DSYNC instead, if available. */
flags |= O_DSYNC;
#if defined(UV_FS_O_DSYNC)
flags |= UV_FS_O_DSYNC;
#endif

rv = uvFsOpenFile(dir, filename, flags, S_IRUSR | S_IWUSR, fd, errmsg);
if (rv != 0) {
Expand All @@ -204,6 +212,11 @@ int UvFsAllocateFile(const char *dir,
}
goto err_after_open;
}
rv = UvOsFsync(*fd);
if (rv != 0) {
UvOsErrMsg(errmsg, "fsync", rv);
goto err_after_open;
}

return 0;

Expand All @@ -226,6 +239,9 @@ static int uvFsWriteFile(const char *dir,
int rv;
size_t size;
unsigned i;
#ifdef _WIN32
uv_buf_t convBufArr[n_bufs];
#endif
size = 0;
for (i = 0; i < n_bufs; i++) {
size += bufs[i].len;
Expand All @@ -234,7 +250,18 @@ static int uvFsWriteFile(const char *dir,
if (rv != 0) {
goto err;
}
#ifdef _WIN32
// casting raft_buffer to uv_buf_t changes the value of the len field.
// uv_buf_t for Windows is ULONG, while for linux it's size_t. Copying
// the values and explicitly casting len to ULONG seems to work.
for (i = 0; i < n_bufs; i++) {
convBufArr[i].len = (unsigned long)bufs[i].len;
convBufArr[i].base = bufs[i].base;
}
rv = UvOsWrite(fd, convBufArr, n_bufs, 0);
#else
rv = UvOsWrite(fd, (const uv_buf_t *)bufs, n_bufs, 0);
#endif
if (rv != (int)(size)) {
if (rv < 0) {
UvOsErrMsg(errmsg, "write", rv);
Expand Down Expand Up @@ -381,7 +408,14 @@ int UvFsMakeOrOverwriteFile(const char *dir,
goto err;
}

#ifdef WINDOWS
uv_buf_t convBufArr[1];
convBufArr[0].len = (unsigned long)buf->len;
convBufArr[0].base = buf->base;
rv = UvOsWrite(fd, convBufArr, 1, 0);
#else
rv = UvOsWrite(fd, (const uv_buf_t *)buf, 1, 0);
#endif
if (rv != (int)(buf->len)) {
if (rv < 0) {
UvOsErrMsg(errmsg, "write", rv);
Expand Down Expand Up @@ -593,6 +627,7 @@ int UvFsTruncateAndRenameFile(const char *dir,
return RAFT_IOERR;
}

#ifdef __linux__
/* Check if direct I/O is possible on the given fd. */
static int probeDirectIO(int fd, size_t *size, char *errmsg)
{
Expand Down Expand Up @@ -671,6 +706,7 @@ static int probeDirectIO(int fd, size_t *size, char *errmsg)
*size = 0;
return 0;
}
#endif

#if defined(RWF_NOWAIT)
/* Check if fully non-blocking async I/O is possible on the given fd. */
Expand Down Expand Up @@ -763,6 +799,10 @@ int UvFsProbeCapabilities(const char *dir,
bool *async,
char *errmsg)
{
#ifndef __linux__
*direct = 0;
#endif

int fd; /* File descriptor of the probe file */
int rv;
char ignored[RAFT_ERRMSG_BUF_SIZE];
Expand All @@ -777,11 +817,13 @@ int UvFsProbeCapabilities(const char *dir,
}
UvFsRemoveFile(dir, UV__FS_PROBE_FILE, ignored);

#ifdef __linux__
/* Check if we can use direct I/O. */
rv = probeDirectIO(fd, direct, errmsg);
if (rv != 0) {
goto err_after_file_open;
}
#endif

#if !defined(RWF_NOWAIT)
/* We can't have fully async I/O, since io_submit might potentially block.
Expand All @@ -806,8 +848,10 @@ int UvFsProbeCapabilities(const char *dir,
close(fd);
return 0;

#ifdef __linux__
err_after_file_open:
close(fd);
#endif
err:
return rv;
}
4 changes: 4 additions & 0 deletions src/uv_ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
#ifndef UV_IP_H_
#define UV_IP_H_

#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif

/* Split @address into @host and @port and populate @addr accordingly. */
int uvIpParse(const char *address, struct sockaddr_in *addr);
Expand Down
Loading

0 comments on commit 2d208a0

Please sign in to comment.