Commit 5f68cd82 authored by Yoni Fogel's avatar Yoni Fogel

[t:2216] Merge/windows port of #2216

git-svn-id: file:///svn/toku/tokudb@18191 c7de825b-a66e-492c-adef-691d508d4ae1
parent 6baa2eb6
......@@ -6,6 +6,7 @@
#include <windows.h>
#include <toku_atomic.h>
#include <toku_time.h>
#include <fcntl.h>
int64_t
pread(int fildes, void *buf, size_t nbyte, int64_t offset) {
......@@ -189,6 +190,25 @@ toku_os_full_write (int fd, const void *org_buf, size_t len) {
assert(len == 0);
}
int
toku_os_write (int fd, const void *org_buf, size_t len) {
const uint8_t *buf = org_buf;
while (len > 0) {
ssize_t r;
if (t_write) {
r = t_write(fd, buf, len);
} else {
r = write(fd, buf, len);
}
if (r < 0)
return errno;
len -= r;
buf += r;
}
return 0;
}
// t_fsync exists for testing purposes only
static int (*t_fsync)(int) = 0;
static uint64_t toku_fsync_count;
......@@ -266,3 +286,38 @@ toku_get_fsync_times(uint64_t *fsync_count, uint64_t *fsync_time) {
*fsync_time = toku_fsync_time;
}
static toku_pthread_mutex_t mkstemp_lock;
int
toku_mkstemp_init(void) {
int r = 0;
r = toku_pthread_mutex_init(&mkstemp_lock, NULL); assert(r == 0);
return r;
}
int
toku_mkstemp_destroy(void) {
int r = 0;
r = toku_pthread_mutex_destroy(&mkstemp_lock); assert(r == 0);
return r;
}
int mkstemp (char * template) {
int fd;
int r_mutex;
r_mutex = toku_pthread_mutex_lock(&mkstemp_lock);
assert(r_mutex == 0);
errno_t err = _mktemp_s(template, strlen(template)+1);
if (err!=0) {
fd = -1;
errno = err;
goto cleanup;
}
assert(err==0);
fd = open(template, _O_BINARY|_O_CREAT|_O_SHORT_LIVED|_O_EXCL|_O_RDWR, _S_IREAD|_S_IWRITE);
cleanup:
r_mutex = toku_pthread_mutex_unlock(&mkstemp_lock);
assert(r_mutex == 0);
return fd;
}
......@@ -15,6 +15,8 @@ extern "C" {
int fsync(int fildes);
int toku_fsync_init(void);
int toku_fsync_destroy(void);
int toku_mkstemp_init(void);
int toku_mkstemp_destroy(void);
int gettimeofday(struct timeval *tv, struct timezone *tz);
......@@ -76,6 +78,8 @@ int snprintf(char *str, size_t size, const char *format, ...);
int usleep(unsigned int useconds);
int mkstemp(char * ttemplate);
#if defined(__cplusplus)
};
#endif
......
......@@ -21,12 +21,14 @@ all: $(BINS)
.PHONY: check
check: $(BINS) $(RUNTARGETS);
test-pwrite4g.tdbrun: TEST_EXTRA_ARGS=.
test-pwrite4g.tdbrun: VERBVERBOSE=
%.tdbrun: %$(BINSUF) $(PTHREAD_LOCAL)
mkdir -p dir.$*
ifeq ($(VGRIND),)
cd dir.$* && ../$< $(VERBVERBOSE) $(SUMMARIZE_CMD)
cd dir.$* && ../$< $(TEST_EXTRA_ARGS) $(VERBVERBOSE) $(SUMMARIZE_CMD)
else
cd dir.$* && .$(VGRIND) --log-file=$<.valgrind ../$< $(VERBVERBOSE); \
cd dir.$* && .$(VGRIND) --log-file=$<.valgrind ../$< $(TEST_EXTRA_ARGS) $(VERBVERBOSE); \
if [ $$? = 0 ] ; then \
grep "LEAK SUMMARY" dir.$*/$<.valgrind >/dev/null 2>&1; \
if [ $$? = 0 ] ; then cat dir.$*/$<.valgrind; test 0 = 1; fi \
......
#define _CRT_SECURE_NO_DEPRECATE
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <toku_assert.h>
#include <fcntl.h>
#include <test.h>
#include "toku_os.h"
#include <dirent.h>
......@@ -33,7 +33,7 @@ static int walk(const char *dirname) {
return otherfound;
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
int found;
int fd;
......
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <toku_assert.h>
#include <fcntl.h>
#include <test.h>
#include "toku_os.h"
int verbose=0;
enum {NUM_IDS=4};
struct fileid old_ids[NUM_IDS];
BOOL valid[NUM_IDS];
//TODO: Test that different files are different,
// other stuff
static void test_handles(const char *fname) {
static void test_handles(const char *fname, unsigned which) {
unlink(fname);
int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO);
assert(fd!=-1);
......@@ -18,17 +20,34 @@ static void test_handles(const char *fname) {
struct fileid id_base;
struct fileid id;
int r = toku_os_get_unique_file_id(fd, &id_base);
assert(r==0);
CKERR(r);
assert(which < NUM_IDS);
for (i = 0; i < NUM_IDS; i++) {
if (valid[i]) {
if (which==i) {
//Assert same
assert(memcmp(&id_base, &old_ids[i], sizeof(id_base))==0);
}
else {
//Assert different
assert(memcmp(&id_base, &old_ids[i], sizeof(id_base))!=0);
}
}
}
memcpy(&old_ids[which], &id_base, sizeof(id_base));
valid[which] = TRUE;
if (verbose) printf("[%s] : r=[%d] errno=[%d] id=[0x%"PRIx32"/0x%"PRIx64"]\n", fname, r, errno, id_base.st_dev, id_base.st_ino);
for (i=0; i < 1<<16; i++) {
r = toku_os_get_unique_file_id(fd, &id);
assert(r==0);
CKERR(r);
assert(memcmp(&id, &id_base, sizeof(id))==0);
}
r = close(fd);
assert(r==0);
CKERR(r);
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
for (i=1; i<argc; i++) {
......@@ -37,7 +56,13 @@ int test_main(int argc, char *argv[]) {
verbose++;
}
test_handles("junk");
test_handles("junk1", 0);
test_handles("junk2", 1);
test_handles("junk3", 2);
test_handles("NUL", 3);
test_handles(".\\NUL", 3);
test_handles("\\NUL", 3);
test_handles("C:\\NUL", 3);
return 0;
}
......@@ -27,7 +27,7 @@ static int ftruncate(int fd, uint64_t offset) {
}
#endif
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int r;
int fd;
......
......@@ -3,7 +3,7 @@
#include <toku_assert.h>
#include <toku_time.h>
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int r;
struct timeval tv;
struct timezone tz;
......
#define _GNU_SOURCE
#include <test.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <unistd.h>
#include <toku_assert.h>
#include <test.h>
#include <toku_os.h>
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
uint64_t maxdata;
int r = toku_os_get_max_process_data_size(&maxdata);
assert(r == 0);
......
......@@ -6,7 +6,7 @@
#include <errno.h>
#include <fcntl.h>
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
for (i=1; i<argc; i++) {
int fd = open(argv[i], O_RDONLY);
......
......@@ -19,7 +19,7 @@
#define TESTFILE "test-open-unlink-file"
#define NEWNAME TESTFILE ".junk"
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int r;
int fd;
......
......@@ -18,7 +18,7 @@
const char TESTFILE[] = "test-open-unlink-file";
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int r;
int fd;
......
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <toku_assert.h>
#include <fcntl.h>
#include <test.h>
#include "toku_os.h"
int verbose;
......@@ -24,7 +24,7 @@ static void test_pread_empty(const char *fname) {
printf("close %s %"PRIu64"\n", fname, r);
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
for (i=1; i<argc; i++) {
......
......@@ -68,7 +68,7 @@ static void *reader(void *arg) {
return arg;
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
void *ret;
toku_pthread_t t[2];
......
......@@ -20,7 +20,7 @@ static void *myfunc2(void *arg) {
return arg;
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
#define N 10
toku_pthread_t t[N];
int i;
......
......@@ -12,7 +12,7 @@ static void *mythreadfunc(void *arg) {
return arg;
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
#define N 1000000
int i;
......
#include <toku_assert.h>
#include <test.h>
#include <toku_assert.h>
#include <toku_pthread.h>
#include <stdio.h>
#include <unistd.h>
int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribute__((__unused__))) {
int test_main(int argc, char *const argv[]) {
int r;
toku_pthread_rwlock_t rwlock;
......
#include <toku_assert.h>
#include <test.h>
#include <toku_assert.h>
#include <toku_pthread.h>
#include <stdio.h>
#include <unistd.h>
......@@ -15,7 +15,7 @@ static void *f(void *arg) {
return arg;
}
int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribute__((__unused__))) {
int test_main(int argc, char *const argv[]) {
int r;
toku_pthread_rwlock_t rwlock;
toku_pthread_t tid;
......
/* Verify that toku_os_full_pwrite does the right thing when writing beyond 4GB. */
#include <test.h>
#include <fcntl.h>
#include <string.h>
#include <toku_assert.h>
#include <test.h>
#include <string.h>
#include <stdio.h>
static int iszero(char *cp, size_t n) {
size_t i;
......@@ -12,8 +13,12 @@ static int iszero(char *cp, size_t n) {
return 1;
}
int test_main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
char fname[] = "pwrite4g.data";
int test_main(int argc, char *const argv[]) {
assert(argc==2); // first arg is the directory to put the data file into.
char short_fname[] = "pwrite4g.data";
int fname_len = strlen(short_fname) + strlen(argv[1]) + 5;
char fname[fname_len];
snprintf(fname, fname_len, "%s/%s", argv[1], short_fname);
int r;
unlink(fname);
int fd = open(fname, O_RDWR | O_CREAT | O_BINARY, S_IRWXU|S_IRWXG|S_IRWXO);
......
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <toku_assert.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <test.h>
#include <toku_os.h>
static void do_mallocs(void) {
......@@ -16,7 +16,7 @@ static void do_mallocs(void) {
}
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int64_t rss;
toku_os_get_max_rss(&rss);
......
......@@ -7,7 +7,7 @@
int verbose;
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
for (i=1; i<argc; i++) {
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <test.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <toku_portability.h>
#include <toku_assert.h>
#include <toku_os.h>
#include <test.h>
static void
check_snprintf(int i) {
......@@ -37,7 +37,7 @@ check_snprintf(int i) {
}
int test_main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
int test_main(int argc, char *const argv[]) {
int i;
for (i = 0; i < 8; i++) {
check_snprintf(i);
......
......@@ -15,7 +15,7 @@ void test_stat(char *dirname, int result, int ex_errno) {
if (r!=0) assert(errno == ex_errno);
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int r;
test_stat(".", 0, 0);
......
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <toku_assert.h>
#include <test.h>
#include "toku_os.h"
int verbose;
......@@ -17,7 +17,7 @@ void testit(int64_t i, int base) {
assert(i == o);
}
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
int64_t n;
int64_t o;
......
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <toku_assert.h>
#include <fcntl.h>
#include <test.h>
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int r;
int fd;
struct fileid fid;
......
#include <test.h>
#include <stdio.h>
#include <stdlib.h>
#include <toku_assert.h>
......@@ -5,7 +6,7 @@
#include <windows.h>
#include <winsock.h>
int usleep(SOCKET s, unsigned int useconds) {
int usleep_socket(SOCKET s, unsigned int useconds) {
fd_set dummy;
struct timeval tv;
FD_ZERO(&dummy);
......@@ -15,10 +16,9 @@ int usleep(SOCKET s, unsigned int useconds) {
return select(0, 0, 0, &dummy, &tv);
}
#include <test.h>
int verbose;
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
int n = 1;
WSADATA wsadata;
......@@ -39,7 +39,7 @@ int test_main(int argc, char *argv[]) {
if (verbose) {
printf("usleep %d\n", i); fflush(stdout);
}
usleep(s, n);
usleep_socket(s, n);
}
return 0;
......
......@@ -7,7 +7,7 @@
int verbose;
int test_main(int argc, char *argv[]) {
int test_main(int argc, char *const argv[]) {
int i;
int n = 1;
......
#include <toku_portability.h>
#include <toku_assert.h>
#define CKERR(r) do { if (r!=0) fprintf(stderr, "%s:%d error %d %s\n", __FILE__, __LINE__, r, strerror(r)); assert(r==0); } while (0)
#define CKERR2(r,r2) do { if (r!=r2) fprintf(stderr, "%s:%d error %d %s, expected %d\n", __FILE__, __LINE__, r, strerror(r), r2); assert(r==r2); } while (0)
#define CKERR2s(r,r2,r3) do { if (r!=r2 && r!=r3) fprintf(stderr, "%s:%d error %d %s, expected %d or %d\n", __FILE__, __LINE__, r, strerror(r), r2,r3); assert(r==r2||r==r3); } while (0)
#define DEBUG_LINE do { \
fprintf(stderr, "%s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
fflush(stderr); \
} while (0)
int test_main(int argc, char *const argv[]);
int
......
......@@ -48,6 +48,8 @@ toku_portability_init(void) {
r = toku_pthread_win32_init();
if (r==0)
r = toku_fsync_init();
if (r==0)
r = toku_mkstemp_init();
if (r==0)
_fmode = _O_BINARY; //Default open file is BINARY
return r;
......@@ -56,6 +58,8 @@ toku_portability_init(void) {
int
toku_portability_destroy(void) {
int r = 0;
if (r==0)
r = toku_mkstemp_destroy();
if (r==0)
r = toku_fsync_destroy();
if (r==0)
......@@ -115,6 +119,7 @@ toku_os_get_unique_file_id(int fildes, struct fileid *id) {
HANDLE filehandle;
memset(id, 0, sizeof(*id));
memset(&info, 0, sizeof(info));
filehandle = (HANDLE)_get_osfhandle(fildes);
if (filehandle==INVALID_HANDLE_VALUE) {
r = errno; assert(r!=0);
......@@ -123,15 +128,28 @@ toku_os_get_unique_file_id(int fildes, struct fileid *id) {
r = GetFileInformationByHandle(filehandle, &info);
if (r==0) { //0 is error here.
r = GetLastError(); assert(r!=0);
if (r==ERROR_INVALID_FUNCTION && info.dwVolumeSerialNumber == 0 &&
info.nFileIndexHigh == 0 && info.nFileIndexLow == 0) {
//"NUL" will return this.
//TODO: Remove this hack somehow
r = 0;
goto continue_dev_null;
}
goto cleanup;
}
//Make sure only "NUL" returns all zeros.
assert(info.dwVolumeSerialNumber!=0 || info.nFileIndexHigh!=0 || info.nFileIndexLow!=0);
continue_dev_null: //Skip zeros check (its allowed here).
id->st_dev = info.dwVolumeSerialNumber;
id->st_ino = info.nFileIndexHigh;
id->st_ino <<= 32;
id->st_ino |= info.nFileIndexLow;
r = 0;
cleanup:
if (r!=0) errno = r;
if (r!=0) {
errno = r;
r = -1;
}
return r;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment