summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
committerAntonin Kral <a.kral@bobek.cz>2012-08-29 20:54:51 +0200
commit83957b73f9177f6e38bd5375bd93ca1f6a47188c (patch)
treef20b7d6ac9a9c64ff5bb6b5910a24abbb356b1d5 /util
parent5071d203970edd4c995493d810abe20987e76fe9 (diff)
Imported Upstream version 2.2.0upstream/2.2.0
Diffstat (limited to 'util')
-rw-r--r--util/admin_access.h52
-rw-r--r--util/alignedbuilder.cpp141
-rw-r--r--util/alignedbuilder.h125
-rw-r--r--util/allocator.h37
-rw-r--r--util/array.h127
-rw-r--r--util/assert_util.cpp203
-rw-r--r--util/assert_util.h249
-rw-r--r--util/background.cpp190
-rw-r--r--util/background.h155
-rw-r--r--util/base64.cpp109
-rw-r--r--util/base64.h68
-rw-r--r--util/bson_util.h42
-rw-r--r--util/bufreader.h100
-rw-r--r--util/checksum.h37
-rw-r--r--util/compress.cpp31
-rw-r--r--util/compress.h21
-rw-r--r--util/concurrency/README19
-rw-r--r--util/concurrency/list.h97
-rw-r--r--util/concurrency/msg.h61
-rw-r--r--util/concurrency/mutex.h279
-rw-r--r--util/concurrency/mvar.h116
-rw-r--r--util/concurrency/race.h115
-rw-r--r--util/concurrency/rwlock.h396
-rw-r--r--util/concurrency/shared_mutex_win.hpp594
-rw-r--r--util/concurrency/spin_lock.cpp128
-rw-r--r--util/concurrency/spin_lock.h63
-rw-r--r--util/concurrency/synchronization.cpp78
-rw-r--r--util/concurrency/synchronization.h85
-rw-r--r--util/concurrency/task.cpp180
-rw-r--r--util/concurrency/task.h72
-rw-r--r--util/concurrency/thread_pool.cpp141
-rw-r--r--util/concurrency/thread_pool.h82
-rw-r--r--util/concurrency/value.h132
-rw-r--r--util/concurrency/vars.cpp52
-rw-r--r--util/debug_util.cpp60
-rw-r--r--util/debug_util.h106
-rw-r--r--util/embedded_builder.h92
-rw-r--r--util/file.h230
-rw-r--r--util/file_allocator.cpp329
-rw-r--r--util/file_allocator.h91
-rw-r--r--util/goodies.h508
-rw-r--r--util/hashtab.h179
-rw-r--r--util/heapcheck.h33
-rw-r--r--util/hex.h67
-rw-r--r--util/histogram.cpp131
-rw-r--r--util/histogram.h128
-rw-r--r--util/log.cpp173
-rw-r--r--util/log.h531
-rw-r--r--util/logfile.cpp217
-rw-r--r--util/logfile.h53
-rw-r--r--util/lruishmap.h78
-rw-r--r--util/md5.c381
-rw-r--r--util/md5.h91
-rw-r--r--util/md5.hpp58
-rw-r--r--util/md5main.cpp142
-rw-r--r--util/mmap.cpp197
-rw-r--r--util/mmap.h280
-rw-r--r--util/mmap_mm.cpp52
-rw-r--r--util/mmap_posix.cpp214
-rw-r--r--util/mmap_win.cpp269
-rwxr-xr-xutil/mongoutils/README15
-rw-r--r--util/mongoutils/checksum.h32
-rw-r--r--util/mongoutils/hash.h41
-rw-r--r--util/mongoutils/html.h158
-rwxr-xr-xutil/mongoutils/mongoutils.vcxproj75
-rwxr-xr-xutil/mongoutils/mongoutils.vcxproj.filters10
-rw-r--r--util/mongoutils/str.h208
-rw-r--r--util/mongoutils/test.cpp45
-rw-r--r--util/moveablebuffer.h51
-rw-r--r--util/net/hostandport.h165
-rw-r--r--util/net/httpclient.cpp177
-rw-r--r--util/net/httpclient.h78
-rw-r--r--util/net/listen.cpp391
-rw-r--r--util/net/listen.h194
-rw-r--r--util/net/message.cpp64
-rw-r--r--util/net/message.h312
-rw-r--r--util/net/message_port.cpp299
-rw-r--r--util/net/message_port.h107
-rw-r--r--util/net/message_server.h66
-rw-r--r--util/net/message_server_asio.cpp261
-rw-r--r--util/net/message_server_port.cpp201
-rw-r--r--util/net/miniwebserver.cpp212
-rw-r--r--util/net/miniwebserver.h60
-rw-r--r--util/net/sock.cpp782
-rw-r--r--util/net/sock.h256
-rw-r--r--util/ntservice.cpp371
-rw-r--r--util/ntservice.h49
-rw-r--r--util/optime.h152
-rw-r--r--util/password.cpp91
-rw-r--r--util/password.h61
-rw-r--r--util/paths.h117
-rw-r--r--util/processinfo.cpp62
-rw-r--r--util/processinfo.h67
-rw-r--r--util/processinfo_darwin.cpp116
-rw-r--r--util/processinfo_linux2.cpp242
-rw-r--r--util/processinfo_none.cpp55
-rw-r--r--util/processinfo_win32.cpp84
-rw-r--r--util/queue.h106
-rw-r--r--util/ramlog.cpp190
-rw-r--r--util/ramlog.h65
-rw-r--r--util/scopeguard.h432
-rw-r--r--util/signal_handlers.cpp122
-rw-r--r--util/signal_handlers.h34
-rw-r--r--util/stringutils.cpp44
-rw-r--r--util/stringutils.h139
-rw-r--r--util/text.cpp115
-rw-r--r--util/text.h148
-rw-r--r--util/time_support.h253
-rw-r--r--util/timer.h104
-rw-r--r--util/unittest.h62
-rw-r--r--util/util.cpp207
-rw-r--r--util/version.cpp284
-rw-r--r--util/version.h27
-rw-r--r--util/winutil.h44
114 files changed, 0 insertions, 17170 deletions
diff --git a/util/admin_access.h b/util/admin_access.h
deleted file mode 100644
index bb882b2b4c5..00000000000
--- a/util/admin_access.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/** @file admin_access.h
- */
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-namespace mongo {
-
- /*
- * An AdminAccess is an interface class used to determine if certain users have
- * priviledges to a given resource.
- *
- */
- class AdminAccess {
- public:
- virtual ~AdminAccess() { }
-
- /** @return if there are any priviledge users. This should not
- * block for long and throw if can't get a lock if needed.
- */
- virtual bool haveAdminUsers() const = 0;
-
- /** @return priviledged user with this name. This should not block
- * for long and throw if can't get a lock if needed
- */
- virtual BSONObj getAdminUser( const string& username ) const = 0;
- };
-
- class NoAdminAccess : public AdminAccess {
- public:
- virtual ~NoAdminAccess() { }
-
- virtual bool haveAdminUsers() const { return false; }
- virtual BSONObj getAdminUser( const string& username ) const { return BSONObj(); }
- };
-
-} // namespace mongo
diff --git a/util/alignedbuilder.cpp b/util/alignedbuilder.cpp
deleted file mode 100644
index b2e0461b733..00000000000
--- a/util/alignedbuilder.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-// @file alignedbuilder.cpp
-
-/**
-* Copyright (C) 2009 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-#include "alignedbuilder.h"
-
-namespace mongo {
-
- AlignedBuilder::AlignedBuilder(unsigned initSize) {
- _len = 0;
- _malloc(initSize);
- uassert(13584, "out of memory AlignedBuilder", _p._allocationAddress);
- }
-
- BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(size_t));
-
- /** reset for a re-use. shrinks if > 128MB */
- void AlignedBuilder::reset() {
- _len = 0;
- RARELY {
- const unsigned sizeCap = 128*1024*1024;
- if (_p._size > sizeCap)
- _realloc(sizeCap, _len);
- }
- }
-
- /** reset with a hint as to the upcoming needed size specified */
- void AlignedBuilder::reset(unsigned sz) {
- _len = 0;
- unsigned Q = 32 * 1024 * 1024 - 1;
- unsigned want = (sz+Q) & (~Q);
- if( _p._size == want ) {
- return;
- }
- if( _p._size > want ) {
- if( _p._size <= 64 * 1024 * 1024 )
- return;
- bool downsize = false;
- RARELY { downsize = true; }
- if( !downsize )
- return;
- }
- _realloc(want, _len);
- }
-
- void AlignedBuilder::mallocSelfAligned(unsigned sz) {
- assert( sz == _p._size );
- void *p = malloc(sz + Alignment - 1);
- _p._allocationAddress = p;
- size_t s = (size_t) p;
- size_t sold = s;
- s += Alignment - 1;
- s = (s/Alignment)*Alignment;
- assert( s >= sold ); // begining
- assert( (s + sz) <= (sold + sz + Alignment - 1) ); //end
- _p._data = (char *) s;
- }
-
- /* "slow"/infrequent portion of 'grow()' */
- void NOINLINE_DECL AlignedBuilder::growReallocate(unsigned oldLen) {
- dassert( _len > _p._size );
- unsigned a = _p._size;
- assert( a );
- while( 1 ) {
- if( a < 128 * 1024 * 1024 )
- a *= 2;
- else if( sizeof(int*) == 4 )
- a += 32 * 1024 * 1024;
- else
- a += 64 * 1024 * 1024;
- DEV if( a > 256*1024*1024 ) {
- log() << "dur AlignedBuilder too big, aborting in _DEBUG build" << endl;
- abort();
- }
- wassert( a <= 256*1024*1024 );
- assert( a <= 512*1024*1024 );
- if( _len < a )
- break;
- }
- _realloc(a, oldLen);
- }
-
- void AlignedBuilder::_malloc(unsigned sz) {
- _p._size = sz;
-#if defined(_WIN32)
- void *p = VirtualAlloc(0, sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- _p._allocationAddress = p;
- _p._data = (char *) p;
-#elif defined(__linux__)
- // in theory #ifdef _POSIX_VERSION should work, but it doesn't on OS X 10.4, and needs to be testeed on solaris.
- // so for now, linux only for this.
- void *p = 0;
- int res = posix_memalign(&p, Alignment, sz);
- massert(13524, "out of memory AlignedBuilder", res == 0);
- _p._allocationAddress = p;
- _p._data = (char *) p;
-#else
- mallocSelfAligned(sz);
- assert( ((size_t) _p._data) % Alignment == 0 );
-#endif
- }
-
- void AlignedBuilder::_realloc(unsigned newSize, unsigned oldLen) {
- // posix_memalign alignment is not maintained on reallocs, so we can't use realloc().
- AllocationInfo old = _p;
- _malloc(newSize);
- assert( oldLen <= _len );
- memcpy(_p._data, old._data, oldLen);
- _free(old._allocationAddress);
- }
-
- void AlignedBuilder::_free(void *p) {
-#if defined(_WIN32)
- VirtualFree(p, 0, MEM_RELEASE);
-#else
- free(p);
-#endif
- }
-
- void AlignedBuilder::kill() {
- _free(_p._allocationAddress);
- _p._allocationAddress = 0;
- _p._data = 0;
- }
-
-}
diff --git a/util/alignedbuilder.h b/util/alignedbuilder.h
deleted file mode 100644
index 1d246a9d78e..00000000000
--- a/util/alignedbuilder.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// @file alignedbuilder.h
-
-/**
-* Copyright (C) 2009 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "../bson/stringdata.h"
-
-namespace mongo {
-
- /** a page-aligned BufBuilder. */
- class AlignedBuilder {
- public:
- AlignedBuilder(unsigned init_size);
- ~AlignedBuilder() { kill(); }
-
- /** reset with a hint as to the upcoming needed size specified */
- void reset(unsigned sz);
-
- /** reset for a re-use. shrinks if > 128MB */
- void reset();
-
- /** note this may be deallocated (realloced) if you keep writing or reset(). */
- const char* buf() const { return _p._data; }
-
- /** leave room for some stuff later
- @return offset in the buffer that was our current position
- */
- size_t skip(unsigned n) {
- unsigned l = len();
- grow(n);
- return l;
- }
-
- /** if buffer grows pointer no longer valid */
- char* atOfs(unsigned ofs) { return _p._data + ofs; }
-
- /** if buffer grows pointer no longer valid */
- char* cur() { return _p._data + _len; }
-
- void appendChar(char j) {
- *((char*)grow(sizeof(char))) = j;
- }
- void appendNum(char j) {
- *((char*)grow(sizeof(char))) = j;
- }
- void appendNum(short j) {
- *((short*)grow(sizeof(short))) = j;
- }
- void appendNum(int j) {
- *((int*)grow(sizeof(int))) = j;
- }
- void appendNum(unsigned j) {
- *((unsigned*)grow(sizeof(unsigned))) = j;
- }
- void appendNum(bool j) {
- *((bool*)grow(sizeof(bool))) = j;
- }
- void appendNum(double j) {
- *((double*)grow(sizeof(double))) = j;
- }
- void appendNum(long long j) {
- *((long long*)grow(sizeof(long long))) = j;
- }
- void appendNum(unsigned long long j) {
- *((unsigned long long*)grow(sizeof(unsigned long long))) = j;
- }
-
- void appendBuf(const void *src, size_t len) { memcpy(grow((unsigned) len), src, len); }
-
- template<class T>
- void appendStruct(const T& s) { appendBuf(&s, sizeof(T)); }
-
- void appendStr(const StringData &str , bool includeEOO = true ) {
- const unsigned len = str.size() + ( includeEOO ? 1 : 0 );
- assert( len < (unsigned) BSONObjMaxUserSize );
- memcpy(grow(len), str.data(), len);
- }
-
- /** @return the in-use length */
- unsigned len() const { return _len; }
-
- private:
- static const unsigned Alignment = 8192;
-
- /** returns the pre-grow write position */
- inline char* grow(unsigned by) {
- unsigned oldlen = _len;
- _len += by;
- if (MONGO_unlikely( _len > _p._size )) {
- growReallocate(oldlen);
- }
- return _p._data + oldlen;
- }
-
- void growReallocate(unsigned oldLenInUse);
- void kill();
- void mallocSelfAligned(unsigned sz);
- void _malloc(unsigned sz);
- void _realloc(unsigned newSize, unsigned oldLenInUse);
- void _free(void*);
-
- struct AllocationInfo {
- char *_data;
- void *_allocationAddress;
- unsigned _size;
- } _p;
- unsigned _len; // bytes in use
- };
-
-}
diff --git a/util/allocator.h b/util/allocator.h
deleted file mode 100644
index 23ee4ee47b0..00000000000
--- a/util/allocator.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// allocator.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
-
- inline void * ourmalloc(size_t size) {
- void *x = malloc(size);
- if ( x == 0 ) dbexit( EXIT_OOM_MALLOC , "malloc fails");
- return x;
- }
-
- inline void * ourrealloc(void *ptr, size_t size) {
- void *x = realloc(ptr, size);
- if ( x == 0 ) dbexit( EXIT_OOM_REALLOC , "realloc fails");
- return x;
- }
-
-#define MONGO_malloc mongo::ourmalloc
-#define MONGO_realloc mongo::ourrealloc
-
-} // namespace mongo
diff --git a/util/array.h b/util/array.h
deleted file mode 100644
index 12822252fd7..00000000000
--- a/util/array.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// array.h
-
-/*
- * Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace mongo {
-
- /*
- * simple array class that does no allocations
- * same api as vector
- * fixed buffer, so once capacity is exceeded, will assert
- * meant to be-reused with clear()
- */
- template<typename T>
- class FastArray {
- public:
- FastArray( int capacity=10000 )
- : _capacity( capacity ) , _size(0) , _end(this,capacity) {
- _data = new T[capacity];
- }
-
- ~FastArray() {
- delete[] _data;
- }
-
- void clear() {
- _size = 0;
- }
-
- T& operator[]( int x ) {
- assert( x >= 0 && x < _capacity );
- return _data[x];
- }
-
- T& getNext() {
- return _data[_size++];
- }
-
- void push_back( const T& t ) {
- assert( _size < _capacity );
- _data[_size++] = t;
- }
-
- void sort( int (*comp)(const void *, const void *) ) {
- qsort( _data , _size , sizeof(T) , comp );
- }
-
- int size() {
- return _size;
- }
-
- bool hasSpace() {
- return _size < _capacity;
- }
- class iterator {
- public:
- iterator() {
- _it = 0;
- _pos = 0;
- }
-
- iterator( FastArray * it , int pos=0 ) {
- _it = it;
- _pos = pos;
- }
-
- bool operator==(const iterator& other ) const {
- return _pos == other._pos;
- }
-
- bool operator!=(const iterator& other ) const {
- return _pos != other._pos;
- }
-
- void operator++() {
- _pos++;
- }
-
- T& operator*() {
- return _it->_data[_pos];
- }
-
- string toString() const {
- stringstream ss;
- ss << _pos;
- return ss.str();
- }
- private:
- FastArray * _it;
- int _pos;
-
- friend class FastArray;
- };
-
-
- iterator begin() {
- return iterator(this);
- }
-
- iterator end() {
- _end._pos = _size;
- return _end;
- }
-
-
- private:
- int _capacity;
- int _size;
-
- iterator _end;
-
- T * _data;
- };
-}
diff --git a/util/assert_util.cpp b/util/assert_util.cpp
deleted file mode 100644
index da039c09a58..00000000000
--- a/util/assert_util.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-// assert_util.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "assert_util.h"
-#include "assert.h"
-//#include "file.h"
-#include <cmath>
-using namespace std;
-
-#ifndef _WIN32
-#include <cxxabi.h>
-#include <sys/file.h>
-#endif
-
-//#include "../bson/bson.h"
-#include "../db/jsobj.h"
-
-namespace mongo {
-
- AssertionCount assertionCount;
-
- AssertionCount::AssertionCount()
- : regular(0),warning(0),msg(0),user(0),rollovers(0) {
- }
-
- void AssertionCount::rollover() {
- rollovers++;
- regular = 0;
- warning = 0;
- msg = 0;
- user = 0;
- }
-
- void AssertionCount::condrollover( int newvalue ) {
- static int max = (int)pow( 2.0 , 30 );
- if ( newvalue >= max )
- rollover();
- }
-
- void ExceptionInfo::append( BSONObjBuilder& b , const char * m , const char * c ) const {
- if ( msg.empty() )
- b.append( m , "unknown assertion" );
- else
- b.append( m , msg );
-
- if ( code )
- b.append( c , code );
- }
-
- string getDbContext();
-
- /* "warning" assert -- safe to continue, so we don't throw exception. */
- NOINLINE_DECL void wasserted(const char *msg, const char *file, unsigned line) {
- static bool rateLimited;
- static time_t lastWhen;
- static unsigned lastLine;
- if( lastLine == line && time(0)-lastWhen < 5 ) {
- if( rateLimited++ == 0 ) {
- log() << "rate limiting wassert" << endl;
- }
- return;
- }
- lastWhen = time(0);
- lastLine = line;
-
- problem() << "warning assertion failure " << msg << ' ' << file << ' ' << dec << line << endl;
- sayDbContext();
- raiseError(0,msg && *msg ? msg : "wassertion failure");
- assertionCount.condrollover( ++assertionCount.warning );
-#if defined(_DEBUG) || defined(_DURABLEDEFAULTON) || defined(_DURABLEDEFAULTOFF)
- // this is so we notice in buildbot
- log() << "\n\n***aborting after wassert() failure in a debug/test build\n\n" << endl;
- abort();
-#endif
- }
-
- NOINLINE_DECL void asserted(const char *msg, const char *file, unsigned line) {
- assertionCount.condrollover( ++assertionCount.regular );
- problem() << "Assertion failure " << msg << ' ' << file << ' ' << dec << line << endl;
- sayDbContext();
- raiseError(0,msg && *msg ? msg : "assertion failure");
- stringstream temp;
- temp << "assertion " << file << ":" << line;
- AssertionException e(temp.str(),0);
- breakpoint();
-#if defined(_DEBUG) || defined(_DURABLEDEFAULTON) || defined(_DURABLEDEFAULTOFF)
- // this is so we notice in buildbot
- log() << "\n\n***aborting after assert() failure in a debug/test build\n\n" << endl;
- abort();
-#endif
- throw e;
- }
-
- NOINLINE_DECL void verifyFailed( int msgid ) {
- assertionCount.condrollover( ++assertionCount.regular );
- problem() << "Assertion failure " << msgid << endl;
- sayDbContext();
- raiseError(0,"assertion failure");
- stringstream temp;
- temp << msgid;
- AssertionException e(temp.str(),0);
- breakpoint();
-#if defined(_DEBUG) || defined(_DURABLEDEFAULTON) || defined(_DURABLEDEFAULTOFF)
- // this is so we notice in buildbot
- log() << "\n\n***aborting after verify() failure in a debug/test build\n\n" << endl;
- abort();
-#endif
- throw e;
- }
-
- void uassert_nothrow(const char *msg) {
- raiseError(0,msg);
- }
-
- NOINLINE_DECL void uasserted(int msgid, const char *msg) {
- assertionCount.condrollover( ++assertionCount.user );
- LOG(1) << "User Assertion: " << msgid << ":" << msg << endl;
- raiseError(msgid,msg);
- throw UserException(msgid, msg);
- }
-
- NOINLINE_DECL void msgasserted(int msgid, const char *msg) {
- assertionCount.condrollover( ++assertionCount.warning );
- tlog() << "Assertion: " << msgid << ":" << msg << endl;
- raiseError(msgid,msg && *msg ? msg : "massert failure");
- breakpoint();
- printStackTrace();
- throw MsgAssertionException(msgid, msg);
- }
-
- NOINLINE_DECL void msgassertedNoTrace(int msgid, const char *msg) {
- assertionCount.condrollover( ++assertionCount.warning );
- log() << "Assertion: " << msgid << ":" << msg << endl;
- raiseError(msgid,msg && *msg ? msg : "massert failure");
- throw MsgAssertionException(msgid, msg);
- }
-
- NOINLINE_DECL void streamNotGood( int code , string msg , std::ios& myios ) {
- stringstream ss;
- // errno might not work on all systems for streams
- // if it doesn't for a system should deal with here
- ss << msg << " stream invalid: " << errnoWithDescription();
- throw UserException( code , ss.str() );
- }
-
- string errnoWithPrefix( const char * prefix ) {
- stringstream ss;
- if ( prefix )
- ss << prefix << ": ";
- ss << errnoWithDescription();
- return ss.str();
- }
-
- string demangleName( const type_info& typeinfo ) {
-#ifdef _WIN32
- return typeinfo.name();
-#else
- int status;
-
- char * niceName = abi::__cxa_demangle(typeinfo.name(), 0, 0, &status);
- if ( ! niceName )
- return typeinfo.name();
-
- string s = niceName;
- free(niceName);
- return s;
-#endif
- }
-
- NOINLINE_DECL ErrorMsg::ErrorMsg(const char *msg, char ch) {
- int l = strlen(msg);
- assert( l < 128);
- memcpy(buf, msg, l);
- char *p = buf + l;
- p[0] = ch;
- p[1] = 0;
- }
-
- NOINLINE_DECL ErrorMsg::ErrorMsg(const char *msg, unsigned val) {
- int l = strlen(msg);
- assert( l < 128);
- memcpy(buf, msg, l);
- char *p = buf + l;
- sprintf(p, "%u", val);
- }
-
-}
-
diff --git a/util/assert_util.h b/util/assert_util.h
deleted file mode 100644
index c35f651828b..00000000000
--- a/util/assert_util.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// assert_util.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#pragma once
-
-#include "../db/lasterror.h"
-
-// MONGO_NORETURN undefed at end of file
-#ifdef __GNUC__
-# define MONGO_NORETURN __attribute__((__noreturn__))
-#else
-# define MONGO_NORETURN
-#endif
-
-namespace mongo {
-
- enum CommonErrorCodes {
- DatabaseDifferCaseCode = 13297 ,
- StaleConfigInContextCode = 13388
- };
-
- class AssertionCount {
- public:
- AssertionCount();
- void rollover();
- void condrollover( int newValue );
-
- int regular;
- int warning;
- int msg;
- int user;
- int rollovers;
- };
-
- extern AssertionCount assertionCount;
-
- struct ExceptionInfo {
- ExceptionInfo() : msg(""),code(-1) {}
- ExceptionInfo( const char * m , int c )
- : msg( m ) , code( c ) {
- }
- ExceptionInfo( const string& m , int c )
- : msg( m ) , code( c ) {
- }
- void append( BSONObjBuilder& b , const char * m = "$err" , const char * c = "code" ) const ;
- string toString() const { stringstream ss; ss << "exception: " << code << " " << msg; return ss.str(); }
- bool empty() const { return msg.empty(); }
-
- void reset(){ msg = ""; code=-1; }
-
- string msg;
- int code;
- };
-
- /** helper class that builds error strings. lighter weight than a StringBuilder, albeit less flexible.
- NOINLINE_DECL used in the constructor implementations as we are assuming this is a cold code path when used.
-
- example:
- throw UserException(123, ErrorMsg("blah", num_val));
- */
- class ErrorMsg {
- public:
- ErrorMsg(const char *msg, char ch);
- ErrorMsg(const char *msg, unsigned val);
- operator string() const { return buf; }
- private:
- char buf[256];
- };
-
- class DBException : public std::exception {
- public:
- DBException( const ExceptionInfo& ei ) : _ei(ei) {}
- DBException( const char * msg , int code ) : _ei(msg,code) {}
- DBException( const string& msg , int code ) : _ei(msg,code) {}
- virtual ~DBException() throw() { }
-
- virtual const char* what() const throw() { return _ei.msg.c_str(); }
- virtual int getCode() const { return _ei.code; }
-
- virtual void appendPrefix( stringstream& ss ) const { }
-
- virtual string toString() const {
- stringstream ss; ss << getCode() << " " << what(); return ss.str();
- return ss.str();
- }
-
- const ExceptionInfo& getInfo() const { return _ei; }
-
- protected:
- ExceptionInfo _ei;
- };
-
- class AssertionException : public DBException {
- public:
-
- AssertionException( const ExceptionInfo& ei ) : DBException(ei) {}
- AssertionException( const char * msg , int code ) : DBException(msg,code) {}
- AssertionException( const string& msg , int code ) : DBException(msg,code) {}
-
- virtual ~AssertionException() throw() { }
-
- virtual bool severe() { return true; }
- virtual bool isUserAssertion() { return false; }
-
- /* true if an interrupted exception - see KillCurrentOp */
- bool interrupted() {
- return _ei.code == 11600 || _ei.code == 11601;
- }
- };
-
- /* UserExceptions are valid errors that a user can cause, like out of disk space or duplicate key */
- class UserException : public AssertionException {
- public:
- UserException(int c , const string& m) : AssertionException( m , c ) {}
-
- virtual bool severe() { return false; }
- virtual bool isUserAssertion() { return true; }
- virtual void appendPrefix( stringstream& ss ) const { ss << "userassert:"; }
- };
-
- class MsgAssertionException : public AssertionException {
- public:
- MsgAssertionException( const ExceptionInfo& ei ) : AssertionException( ei ) {}
- MsgAssertionException(int c, const string& m) : AssertionException( m , c ) {}
- virtual bool severe() { return false; }
- virtual void appendPrefix( stringstream& ss ) const { ss << "massert:"; }
- };
-
- void asserted(const char *msg, const char *file, unsigned line) MONGO_NORETURN;
- void wasserted(const char *msg, const char *file, unsigned line);
- void verifyFailed( int msgid );
-
- /** a "user assertion". throws UserAssertion. logs. typically used for errors that a user
- could cause, such as duplicate key, disk full, etc.
- */
- void uasserted(int msgid, const char *msg) MONGO_NORETURN;
- inline void uasserted(int msgid , string msg) { uasserted(msgid, msg.c_str()); }
-
- /** reported via lasterror, but don't throw exception */
- void uassert_nothrow(const char *msg);
-
- /** msgassert and massert are for errors that are internal but have a well defined error text string.
- a stack trace is logged.
- */
- void msgassertedNoTrace(int msgid, const char *msg) MONGO_NORETURN;
- inline void msgassertedNoTrace(int msgid, const string& msg) { msgassertedNoTrace( msgid , msg.c_str() ); }
- void msgasserted(int msgid, const char *msg) MONGO_NORETURN;
- inline void msgasserted(int msgid, string msg) { msgasserted(msgid, msg.c_str()); }
-
- /* convert various types of exceptions to strings */
- inline string causedBy( const char* e ){ return (string)" :: caused by :: " + e; }
- inline string causedBy( const DBException& e ){ return causedBy( e.toString().c_str() ); }
- inline string causedBy( const std::exception& e ){ return causedBy( e.what() ); }
- inline string causedBy( const string& e ){ return causedBy( e.c_str() ); }
-
- /** in the mongodb source, use verify() instead of assert(). verify is always evaluated even in release builds. */
- inline void verify( int msgid , bool testOK ) { if ( ! testOK ) verifyFailed( msgid ); }
-
-#define MONGO_assert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::asserted(#_Expression, __FILE__, __LINE__), 0) )
-
- /* "user assert". if asserts, user did something wrong, not our code */
-#define MONGO_uassert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || (mongo::uasserted(msgid, msg), 0) )
-
- /* warning only - keeps going */
-#define MONGO_wassert(_Expression) (void)( MONGO_likely(!!(_Expression)) || (mongo::wasserted(#_Expression, __FILE__, __LINE__), 0) )
-
- /* display a message, no context, and throw assertionexception
-
- easy way to throw an exception and log something without our stack trace
- display happening.
- */
-#define MONGO_massert(msgid, msg, expr) (void)( MONGO_likely(!!(expr)) || (mongo::msgasserted(msgid, msg), 0) )
-
- /* dassert is 'debug assert' -- might want to turn off for production as these
- could be slow.
- */
-#if defined(_DEBUG)
-# define MONGO_dassert assert
-#else
-# define MONGO_dassert(x)
-#endif
-
- // some special ids that we want to duplicate
-
- // > 10000 asserts
- // < 10000 UserException
-
- enum { ASSERT_ID_DUPKEY = 11000 };
-
- /* throws a uassertion with an appropriate msg */
- void streamNotGood( int code , string msg , std::ios& myios ) MONGO_NORETURN;
-
- inline void assertStreamGood(unsigned msgid, string msg, std::ios& myios) {
- if( !myios.good() ) streamNotGood(msgid, msg, myios);
- }
-
- string demangleName( const type_info& typeinfo );
-
-} // namespace mongo
-
-#define BOOST_CHECK_EXCEPTION MONGO_BOOST_CHECK_EXCEPTION
-#define MONGO_BOOST_CHECK_EXCEPTION( expression ) \
- try { \
- expression; \
- } catch ( const std::exception &e ) { \
- stringstream ss; \
- ss << "caught boost exception: " << e.what() << ' ' << __FILE__ << ' ' << __LINE__; \
- msgasserted( 13294 , ss.str() ); \
- } catch ( ... ) { \
- massert( 10437 , "unknown boost failed" , false ); \
- }
-
-#define MONGO_BOOST_CHECK_EXCEPTION_WITH_MSG( expression, msg ) \
- try { \
- expression; \
- } catch ( const std::exception &e ) { \
- stringstream ss; \
- ss << msg << " caught boost exception: " << e.what(); \
- msgasserted( 14043 , ss.str() ); \
- } catch ( ... ) { \
- msgasserted( 14044 , string("unknown boost failed ") + msg ); \
- }
-
-#define DESTRUCTOR_GUARD MONGO_DESTRUCTOR_GUARD
-#define MONGO_DESTRUCTOR_GUARD( expression ) \
- try { \
- expression; \
- } catch ( const std::exception &e ) { \
- problem() << "caught exception (" << e.what() << ") in destructor (" << __FUNCTION__ << ")" << endl; \
- } catch ( ... ) { \
- problem() << "caught unknown exception in destructor (" << __FUNCTION__ << ")" << endl; \
- }
-
-#undef MONGO_NORETURN
diff --git a/util/background.cpp b/util/background.cpp
deleted file mode 100644
index 215b27155a4..00000000000
--- a/util/background.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-// @file background.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-
-#include "concurrency/mutex.h"
-#include "concurrency/spin_lock.h"
-
-#include "background.h"
-#include "time_support.h"
-#include "timer.h"
-
-#include "mongoutils/str.h"
-
-namespace mongo {
-
- // both the BackgroundJob and the internal thread point to JobStatus
- struct BackgroundJob::JobStatus {
- JobStatus( bool delFlag )
- : deleteSelf(delFlag), m("backgroundJob"), state(NotStarted) { }
-
- const bool deleteSelf;
-
- mongo::mutex m; // protects state below
- boost::condition finished; // means _state == Done
- State state;
- };
-
- BackgroundJob::BackgroundJob( bool selfDelete ) {
- _status.reset( new JobStatus( selfDelete ) );
- }
-
- // Background object can be only be destroyed after jobBody() ran
- void BackgroundJob::jobBody( boost::shared_ptr<JobStatus> status ) {
- LOG(1) << "BackgroundJob starting: " << name() << endl;
- {
- scoped_lock l( status->m );
- massert( 13643 , mongoutils::str::stream() << "backgroundjob already started: " << name() , status->state == NotStarted );
- status->state = Running;
- }
-
- const string threadName = name();
- if( ! threadName.empty() )
- setThreadName( threadName.c_str() );
-
- try {
- run();
- }
- catch ( std::exception& e ) {
- log( LL_ERROR ) << "backgroundjob " << name() << "error: " << e.what() << endl;
- }
- catch(...) {
- log( LL_ERROR ) << "uncaught exception in BackgroundJob " << name() << endl;
- }
-
- {
- scoped_lock l( status->m );
- status->state = Done;
- status->finished.notify_all();
- }
-
- if( status->deleteSelf )
- delete this;
- }
-
- BackgroundJob& BackgroundJob::go() {
- boost::thread t( boost::bind( &BackgroundJob::jobBody , this, _status ) );
- return *this;
- }
-
- bool BackgroundJob::wait( unsigned msTimeOut ) {
- assert( !_status->deleteSelf ); // you cannot call wait on a self-deleting job
- scoped_lock l( _status->m );
- while ( _status->state != Done ) {
- if ( msTimeOut ) {
- // add msTimeOut millisecond to current time
- boost::xtime xt;
- boost::xtime_get( &xt, boost::TIME_UTC );
-
- unsigned long long ns = msTimeOut * 1000000ULL; // milli to nano
- if ( xt.nsec + ns < 1000000000 ) {
- xt.nsec = (xtime::xtime_nsec_t) (xt.nsec + ns);
- }
- else {
- xt.sec += 1 + ns / 1000000000;
- xt.nsec = ( ns + xt.nsec ) % 1000000000;
- }
-
- if ( ! _status->finished.timed_wait( l.boost() , xt ) )
- return false;
-
- }
- else {
- _status->finished.wait( l.boost() );
- }
- }
- return true;
- }
-
- BackgroundJob::State BackgroundJob::getState() const {
- scoped_lock l( _status->m);
- return _status->state;
- }
-
- bool BackgroundJob::running() const {
- scoped_lock l( _status->m);
- return _status->state == Running;
- }
-
- // -------------------------
-
- PeriodicTask::PeriodicTask() {
- if ( ! theRunner )
- theRunner = new Runner();
- theRunner->add( this );
- }
-
- PeriodicTask::~PeriodicTask() {
- theRunner->remove( this );
- }
-
- void PeriodicTask::Runner::add( PeriodicTask* task ) {
- scoped_spinlock lk( _lock );
- _tasks.push_back( task );
- }
-
- void PeriodicTask::Runner::remove( PeriodicTask* task ) {
- scoped_spinlock lk( _lock );
- for ( size_t i=0; i<_tasks.size(); i++ ) {
- if ( _tasks[i] == task ) {
- _tasks[i] = 0;
- break;
- }
- }
- }
-
- void PeriodicTask::Runner::run() {
- int sleeptime = 60;
- DEV sleeptime = 5; // to catch race conditions
-
- while ( ! inShutdown() ) {
-
- sleepsecs( sleeptime );
-
- scoped_spinlock lk( _lock );
-
- size_t size = _tasks.size();
-
- for ( size_t i=0; i<size; i++ ) {
- PeriodicTask * t = _tasks[i];
- if ( ! t )
- continue;
-
- if ( inShutdown() )
- break;
-
- Timer timer;
- try {
- t->taskDoWork();
- }
- catch ( std::exception& e ) {
- error() << "task: " << t->taskName() << " failed: " << e.what() << endl;
- }
- catch ( ... ) {
- error() << "task: " << t->taskName() << " failed with unknown error" << endl;
- }
-
- int ms = timer.millis();
- LOG( ms <= 3 ? 1 : 0 ) << "task: " << t->taskName() << " took: " << ms << "ms" << endl;
- }
- }
- }
-
- PeriodicTask::Runner* PeriodicTask::theRunner = 0;
-
-} // namespace mongo
diff --git a/util/background.h b/util/background.h
deleted file mode 100644
index 496a1f44f88..00000000000
--- a/util/background.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// @file background.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "concurrency/spin_lock.h"
-
-namespace mongo {
-
- /**
- * Background thread dispatching.
- * subclass and define run()
- *
- * It is ok to call go(), that is, run the job, more than once -- if the
- * previous invocation has finished. Thus one pattern of use is to embed
- * a backgroundjob in your object and reuse it (or same thing with
- * inheritance). Each go() call spawns a new thread.
- *
- * Thread safety:
- * note when job destructs, the thread is not terminated if still running.
- * generally if the thread could still be running, allocate the job dynamically
- * and set deleteSelf to true.
- *
- * go() and wait() are not thread safe
- * run() will be executed on the background thread
- * BackgroundJob object must exist for as long the background thread is running
- */
-
- class BackgroundJob : boost::noncopyable {
- protected:
- /**
- * sub-class must intantiate the BackgrounJob
- *
- * @param selfDelete if set to true, object will destruct itself after the run() finished
- * @note selfDelete instantes cannot be wait()-ed upon
- */
- explicit BackgroundJob(bool selfDelete = false);
-
- virtual string name() const = 0;
-
- /**
- * define this to do your work.
- * after this returns, state is set to done.
- * after this returns, deleted if deleteSelf true.
- *
- * NOTE:
- * if run() throws, the exception will be caught within 'this' object and will ultimately lead to the
- * BackgroundJob's thread being finished, as if run() returned.
- *
- */
- virtual void run() = 0;
-
- public:
- enum State {
- NotStarted,
- Running,
- Done
- };
-
- virtual ~BackgroundJob() { }
-
- /**
- * starts job.
- * returns immediatelly after dispatching.
- *
- * @note the BackgroundJob object must live for as long the thread is still running, ie
- * until getState() returns Done.
- */
- BackgroundJob& go();
-
- /**
- * wait for completion.
- *
- * @param msTimeOut maximum amount of time to wait in millisecons
- * @return true if did not time out. false otherwise.
- *
- * @note you can call wait() more than once if the first call times out.
- * but you cannot call wait on a self-deleting job.
- */
- bool wait( unsigned msTimeOut = 0 );
-
- // accessors
- State getState() const;
- bool running() const;
-
- private:
- struct JobStatus;
- boost::shared_ptr<JobStatus> _status; // shared between 'this' and body() thread
-
- void jobBody( boost::shared_ptr<JobStatus> status );
-
- };
-
- /**
- * these run "roughly" every minute
- * instantiate statically
- * class MyTask : public PeriodicTask {
- * public:
- * virtual string name() const { return "MyTask; " }
- * virtual void doWork() { log() << "hi" << endl; }
- * } myTask;
- */
- class PeriodicTask {
- public:
- PeriodicTask();
- virtual ~PeriodicTask();
-
- virtual void taskDoWork() = 0;
- virtual string taskName() const = 0;
-
- class Runner : public BackgroundJob {
- public:
- virtual ~Runner(){}
-
- virtual string name() const { return "PeriodicTask::Runner"; }
-
- virtual void run();
-
- void add( PeriodicTask* task );
- void remove( PeriodicTask* task );
-
- private:
-
- SpinLock _lock;
-
- // these are NOT owned by Runner
- // Runner will not delete these
- // this never gets smaller
- // only fields replaced with nulls
- vector<PeriodicTask*> _tasks;
-
- };
-
- static Runner* theRunner;
-
- };
-
-
-
-
-} // namespace mongo
diff --git a/util/base64.cpp b/util/base64.cpp
deleted file mode 100644
index aff06e26126..00000000000
--- a/util/base64.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-// util/base64.cpp
-
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "base64.h"
-
-namespace mongo {
- namespace base64 {
-
- Alphabet alphabet;
-
- void encode( stringstream& ss , const char * data , int size ) {
- for ( int i=0; i<size; i+=3 ) {
- int left = size - i;
- const unsigned char * start = (const unsigned char*)data + i;
-
- // byte 0
- ss << alphabet.e(start[0]>>2);
-
- // byte 1
- unsigned char temp = ( start[0] << 4 );
- if ( left == 1 ) {
- ss << alphabet.e(temp);
- break;
- }
- temp |= ( ( start[1] >> 4 ) & 0xF );
- ss << alphabet.e(temp);
-
- // byte 2
- temp = ( start[1] & 0xF ) << 2;
- if ( left == 2 ) {
- ss << alphabet.e(temp);
- break;
- }
- temp |= ( ( start[2] >> 6 ) & 0x3 );
- ss << alphabet.e(temp);
-
- // byte 3
- ss << alphabet.e(start[2] & 0x3f);
- }
-
- int mod = size % 3;
- if ( mod == 1 ) {
- ss << "==";
- }
- else if ( mod == 2 ) {
- ss << "=";
- }
- }
-
-
- string encode( const char * data , int size ) {
- stringstream ss;
- encode( ss , data ,size );
- return ss.str();
- }
-
- string encode( const string& s ) {
- return encode( s.c_str() , s.size() );
- }
-
-
- void decode( stringstream& ss , const string& s ) {
- uassert( 10270 , "invalid base64" , s.size() % 4 == 0 );
- const unsigned char * data = (const unsigned char*)s.c_str();
- int size = s.size();
-
- unsigned char buf[3];
- for ( int i=0; i<size; i+=4) {
- const unsigned char * start = data + i;
- buf[0] = ( ( alphabet.decode[start[0]] << 2 ) & 0xFC ) | ( ( alphabet.decode[start[1]] >> 4 ) & 0x3 );
- buf[1] = ( ( alphabet.decode[start[1]] << 4 ) & 0xF0 ) | ( ( alphabet.decode[start[2]] >> 2 ) & 0xF );
- buf[2] = ( ( alphabet.decode[start[2]] << 6 ) & 0xC0 ) | ( ( alphabet.decode[start[3]] & 0x3F ) );
-
- int len = 3;
- if ( start[3] == '=' ) {
- len = 2;
- if ( start[2] == '=' ) {
- len = 1;
- }
- }
- ss.write( (const char*)buf , len );
- }
- }
-
- string decode( const string& s ) {
- stringstream ss;
- decode( ss , s );
- return ss.str();
- }
-
- }
-}
-
diff --git a/util/base64.h b/util/base64.h
deleted file mode 100644
index 505b5d78cca..00000000000
--- a/util/base64.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// util/base64.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
- namespace base64 {
-
- class Alphabet {
- public:
- Alphabet()
- : encode((unsigned char*)
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789"
- "+/")
- , decode(new unsigned char[257]) {
- memset( decode.get() , 0 , 256 );
- for ( int i=0; i<64; i++ ) {
- decode[ encode[i] ] = i;
- }
-
- test();
- }
- void test() {
- assert( strlen( (char*)encode ) == 64 );
- for ( int i=0; i<26; i++ )
- assert( encode[i] == toupper( encode[i+26] ) );
- }
-
- char e( int x ) {
- return encode[x&0x3f];
- }
-
- private:
- const unsigned char * encode;
- public:
- boost::scoped_array<unsigned char> decode;
- };
-
- extern Alphabet alphabet;
-
-
- void encode( stringstream& ss , const char * data , int size );
- string encode( const char * data , int size );
- string encode( const string& s );
-
- void decode( stringstream& ss , const string& s );
- string decode( const string& s );
-
-
- void testAlphabet();
- }
-}
diff --git a/util/bson_util.h b/util/bson_util.h
deleted file mode 100644
index 973e31f1af1..00000000000
--- a/util/bson_util.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// bson_util.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../pch.h"
-
-namespace mongo {
-
-template <typename T>
-void bsonArrToNumVector(BSONElement el, vector<T>& results){
-
- if(el.type() == Array){
-
- vector<BSONElement> elements = el.Array();
-
- for(vector<BSONElement>::iterator i = elements.begin(); i != elements.end(); ++i){
- results.push_back( (T) (*i).Number() );
- }
- }
- else if(el.isNumber()){
- results.push_back( (T) el.Number() );
- }
-
-}
-
-
-}
diff --git a/util/bufreader.h b/util/bufreader.h
deleted file mode 100644
index 53f0ba744e2..00000000000
--- a/util/bufreader.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// @file bufreader.h parse a memory region into usable pieces
-
-/**
-* Copyright (C) 2009 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-namespace mongo {
-
- /** helper to read and parse a block of memory
- methods throw the eof exception if the operation would pass the end of the
- buffer with which we are working.
- */
- class BufReader : boost::noncopyable {
- public:
- class eof : public std::exception {
- public:
- eof() { }
- virtual const char * what() { return "BufReader eof"; }
- };
-
- BufReader(const void *p, unsigned len) : _start(p), _pos(p), _end(((char *)_pos)+len) { }
-
- bool atEof() const { return _pos == _end; }
-
- /** read in the object specified, and advance buffer pointer */
- template <typename T>
- void read(T &t) {
- T* cur = (T*) _pos;
- T *next = cur + 1;
- if( _end < next ) throw eof();
- t = *cur;
- _pos = next;
- }
-
- /** verify we can look at t, but do not advance */
- template <typename T>
- void peek(T &t) {
- T* cur = (T*) _pos;
- T *next = cur + 1;
- if( _end < next ) throw eof();
- t = *cur;
- }
-
- /** return current offset into buffer */
- unsigned offset() const { return (char*)_pos - (char*)_start; }
-
- /** return remaining bytes */
- unsigned remaining() const { return (char*)_end -(char*)_pos; }
-
- /** back up by nbytes */
- void rewind(unsigned nbytes) {
- _pos = ((char *) _pos) - nbytes;
- assert( _pos >= _start );
- }
-
- /** return current position pointer, and advance by len */
- const void* skip(unsigned len) {
- const char *nxt = ((char *) _pos) + len;
- if( _end < nxt ) throw eof();
- const void *p = _pos;
- _pos = nxt;
- return p;
- }
-
- void readStr(string& s) {
- StringBuilder b;
- while( 1 ) {
- char ch;
- read(ch);
- if( ch == 0 )
- break;
- b << ch;
- }
- s = b.str();
- }
-
- const void* pos() { return _pos; }
- const void* start() { return _start; }
-
- private:
- const void *_start;
- const void *_pos;
- const void *_end;
- };
-
-}
diff --git a/util/checksum.h b/util/checksum.h
deleted file mode 100644
index 009ab56fbeb..00000000000
--- a/util/checksum.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-#include "../pch.h"
-namespace mongo {
- /** a simple, rather dumb, but very fast checksum. see perftests.cpp for unit tests. */
- struct Checksum {
- union {
- unsigned char bytes[16];
- unsigned long long words[2];
- };
-
- // if you change this you must bump dur::CurrentVersion
- void gen(const void *buf, unsigned len) {
- wassert( ((size_t)buf) % 8 == 0 ); // performance warning
- unsigned n = len / 8 / 2;
- const unsigned long long *p = (const unsigned long long *) buf;
- unsigned long long a = 0;
- for( unsigned i = 0; i < n; i++ ) {
- a += (*p ^ i);
- p++;
- }
- unsigned long long b = 0;
- for( unsigned i = 0; i < n; i++ ) {
- b += (*p ^ i);
- p++;
- }
- unsigned long long c = 0;
- for( unsigned i = n * 2 * 8; i < len; i++ ) { // 0-7 bytes left
- c = (c << 8) | ((const char *)buf)[i];
- }
- words[0] = a ^ len;
- words[1] = b ^ c;
- }
-
- bool operator==(const Checksum& rhs) const { return words[0]==rhs.words[0] && words[1]==rhs.words[1]; }
- bool operator!=(const Checksum& rhs) const { return words[0]!=rhs.words[0] || words[1]!=rhs.words[1]; }
- };
-}
diff --git a/util/compress.cpp b/util/compress.cpp
deleted file mode 100644
index bcde488b88b..00000000000
--- a/util/compress.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// @file compress.cpp
-
-#include "../third_party/snappy/snappy.h"
-#include "compress.h"
-#include <string>
-#include <string.h>
-#include <assert.h>
-
-namespace mongo {
-
- void rawCompress(const char* input,
- size_t input_length,
- char* compressed,
- size_t* compressed_length)
- {
- snappy::RawCompress(input, input_length, compressed, compressed_length);
- }
-
- size_t maxCompressedLength(size_t source_len) {
- return snappy::MaxCompressedLength(source_len);
- }
-
- size_t compress(const char* input, size_t input_length, std::string* output) {
- return snappy::Compress(input, input_length, output);
- }
-
- bool uncompress(const char* compressed, size_t compressed_length, std::string* uncompressed) {
- return snappy::Uncompress(compressed, compressed_length, uncompressed);
- }
-
-}
diff --git a/util/compress.h b/util/compress.h
deleted file mode 100644
index 5bc5a3392bb..00000000000
--- a/util/compress.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// @file compress.h
-
-#pragma once
-
-#include <string>
-
-namespace mongo {
-
- size_t compress(const char* input, size_t input_length, std::string* output);
-
- bool uncompress(const char* compressed, size_t compressed_length, std::string* uncompressed);
-
- size_t maxCompressedLength(size_t source_len);
- void rawCompress(const char* input,
- size_t input_length,
- char* compressed,
- size_t* compressed_length);
-
-}
-
-
diff --git a/util/concurrency/README b/util/concurrency/README
deleted file mode 100644
index 1d72a1ce4ec..00000000000
--- a/util/concurrency/README
+++ /dev/null
@@ -1,19 +0,0 @@
-util/concurrency/ files
-
-list.h - a list class that is lock-free for reads
-rwlock.h - read/write locks (RWLock)
-msg.h - message passing between threads
-task.h - an abstraction around threads
-mutex.h - small enhancements that wrap boost::mutex
-mvar.h
- This is based on haskell's MVar synchronization primitive:
- http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Control-Concurrent-MVar.html
- It is a thread-safe queue that can hold at most one object.
- You can also think of it as a box that can be either full or empty.
-value.h
- Atomic wrapper for values/objects that are copy constructable / assignable
-thread_pool.h
-spinlock.h
-synchronization.h
- A class to establish a sinchronization point between two threads. One thread is the waiter and one
- is the notifier. After the notification event, both proceed normally.
diff --git a/util/concurrency/list.h b/util/concurrency/list.h
deleted file mode 100644
index 01bae6fa8a2..00000000000
--- a/util/concurrency/list.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// list.h
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-namespace mongo {
-
- /* this class uses a mutex for writes, but not for reads.
- we can get fancier later...
-
- struct Member : public List1<Member>::Base {
- const char *host;
- int port;
- };
- List1<Member> _members;
- _members.head()->next();
-
- */
- template<typename T>
- class List1 : boost::noncopyable {
- public:
- /* next() and head() return 0 at end of list */
-
- List1() : _head(0), _m("List1"), _orphans(0) { }
-
- class Base {
- friend class List1;
- T *_next;
- public:
- Base() : _next(0){}
- ~Base() { wassert(false); } // we never want this to happen
- T* next() const { return _next; }
- };
-
- /** note this is safe:
-
- T* p = mylist.head();
- if( p )
- use(p);
-
- and this is not:
-
- if( mylist.head() )
- use( mylist.head() ); // could become 0
- */
- T* head() const { return (T*) _head; }
-
- void push(T* t) {
- assert( t->_next == 0 );
- scoped_lock lk(_m);
- t->_next = (T*) _head;
- _head = t;
- }
-
- // intentionally leaks.
- void orphanAll() {
- scoped_lock lk(_m);
- _head = 0;
- }
-
- /* t is not deleted, but is removed from the list. (orphaned) */
- void orphan(T* t) {
- scoped_lock lk(_m);
- T *&prev = (T*&) _head;
- T *n = prev;
- while( n != t ) {
- uassert( 14050 , "List1: item to orphan not in list", n );
- prev = n->_next;
- n = prev;
- }
- prev = t->_next;
- if( ++_orphans > 500 )
- log() << "warning List1 orphans=" << _orphans << '\n';
- }
-
- private:
- volatile T *_head;
- mongo::mutex _m;
- int _orphans;
- };
-
-};
diff --git a/util/concurrency/msg.h b/util/concurrency/msg.h
deleted file mode 100644
index f7c6788dadc..00000000000
--- a/util/concurrency/msg.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// @file msg.h - interthread message passing
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,b
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include <deque>
-#include "task.h"
-
-namespace mongo {
-
- namespace task {
-
- typedef boost::function<void()> lam;
-
- /** typical usage is: task::fork( new Server("threadname") ); */
- class Server : public Task {
- public:
- /** send a message to the port */
- void send(lam);
-
- Server(string name) : _name(name), rq(false) { }
- virtual ~Server() { }
-
- /** send message but block until function completes */
- void call(const lam&);
-
- void requeue() { rq = true; }
-
- protected:
- /* REMINDER : for use in mongod, you will want to have this call Client::initThread(). */
- virtual void starting() { }
-
- private:
- virtual bool initClient() { return true; }
- virtual string name() const { return _name; }
- void doWork();
- deque<lam> d;
- boost::mutex m;
- boost::condition c;
- string _name;
- bool rq;
- };
-
- }
-
-}
diff --git a/util/concurrency/mutex.h b/util/concurrency/mutex.h
deleted file mode 100644
index f17c3f0891d..00000000000
--- a/util/concurrency/mutex.h
+++ /dev/null
@@ -1,279 +0,0 @@
-// @file mutex.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <map>
-#include <set>
-#include "../heapcheck.h"
-
-namespace mongo {
-
- void printStackTrace( ostream &o );
-
- class mutex;
-
- inline boost::xtime incxtimemillis( long long s ) {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += (int)( s / 1000 );
- xt.nsec += (int)(( s % 1000 ) * 1000000);
- if ( xt.nsec >= 1000000000 ) {
- xt.nsec -= 1000000000;
- xt.sec++;
- }
- return xt;
- }
-
- /** only used on _DEBUG builds.
- MutexDebugger checks that we always acquire locks for multiple mutexes in a consistant (acyclic) order.
- If we were inconsistent we could deadlock.
- */
- class MutexDebugger {
- typedef const char * mid; // mid = mutex ID
- typedef map<mid,int> Preceeding;
- map< mid, int > maxNest;
- boost::thread_specific_ptr< Preceeding > us;
- map< mid, set<mid> > followers;
- boost::mutex &x;
- unsigned magic;
- void aBreakPoint() { } // for debugging
- public:
- // set these to create an assert that
- // b must never be locked before a
- // so
- // a.lock(); b.lock(); is fine
- // b.lock(); alone is fine too
- // only checked on _DEBUG builds.
- string a,b;
-
- /** outputs some diagnostic info on mutexes (on _DEBUG builds) */
- void programEnding();
-
- MutexDebugger();
-
- void entering(mid m) {
- if( this == 0 ) return;
- assert( magic == 0x12345678 );
-
- Preceeding *_preceeding = us.get();
- if( _preceeding == 0 )
- us.reset( _preceeding = new Preceeding() );
- Preceeding &preceeding = *_preceeding;
-
- if( a == m ) {
- aBreakPoint();
- if( preceeding[b.c_str()] ) {
- cout << "****** MutexDebugger error! warning " << b << " was locked before " << a << endl;
- assert(false);
- }
- }
-
- preceeding[m]++;
- if( preceeding[m] > 1 ) {
- // recursive re-locking.
- if( preceeding[m] > maxNest[m] )
- maxNest[m] = preceeding[m];
- return;
- }
-
- bool failed = false;
- string err;
- {
- boost::mutex::scoped_lock lk(x);
- followers[m];
- for( Preceeding::iterator i = preceeding.begin(); i != preceeding.end(); i++ ) {
- if( m != i->first && i->second > 0 ) {
- followers[i->first].insert(m);
- if( followers[m].count(i->first) != 0 ) {
- failed = true;
- stringstream ss;
- mid bad = i->first;
- ss << "mutex problem" <<
- "\n when locking " << m <<
- "\n " << bad << " was already locked and should not be."
- "\n set a and b above to debug.\n";
- stringstream q;
- for( Preceeding::iterator i = preceeding.begin(); i != preceeding.end(); i++ ) {
- if( i->first != m && i->first != bad && i->second > 0 )
- q << " " << i->first << '\n';
- }
- string also = q.str();
- if( !also.empty() )
- ss << "also locked before " << m << " in this thread (no particular order):\n" << also;
- err = ss.str();
- break;
- }
- }
- }
- }
- if( failed ) {
- cout << err << endl;
- assert( 0 );
- }
- }
- void leaving(mid m) {
- if( this == 0 ) return; // still in startup pre-main()
- Preceeding& preceeding = *us.get();
- preceeding[m]--;
- if( preceeding[m] < 0 ) {
- cout << "ERROR: lock count for " << m << " is " << preceeding[m] << endl;
- assert( preceeding[m] >= 0 );
- }
- }
- };
- extern MutexDebugger &mutexDebugger;
-
- // If you create a local static instance of this class, that instance will be destroyed
- // before all global static objects are destroyed, so _destroyingStatics will be set
- // to true before the global static variables are destroyed.
- class StaticObserver : boost::noncopyable {
- public:
- static bool _destroyingStatics;
- ~StaticObserver() { _destroyingStatics = true; }
- };
-
- /** On pthread systems, it is an error to destroy a mutex while held (boost mutex
- * may use pthread). Static global mutexes may be held upon shutdown in our
- * implementation, and this way we avoid destroying them.
- * NOT recursive.
- */
- class mutex : boost::noncopyable {
- public:
-#if defined(_DEBUG)
- const char * const _name;
- mutex(const char *name) : _name(name)
-#else
- mutex(const char *)
-#endif
- {
- _m = new boost::timed_mutex();
- IGNORE_OBJECT( _m ); // Turn-off heap checking on _m
- }
- ~mutex() {
- if( !StaticObserver::_destroyingStatics ) {
- UNIGNORE_OBJECT( _m );
- delete _m;
- }
- }
-
- class try_lock : boost::noncopyable {
- public:
- try_lock( mongo::mutex &m , int millis = 0 )
- : _l( m.boost() , incxtimemillis( millis ) ) ,
-#if BOOST_VERSION >= 103500
- ok( _l.owns_lock() )
-#else
- ok( _l.locked() )
-#endif
- { }
- private:
- boost::timed_mutex::scoped_timed_lock _l;
- public:
- const bool ok;
- };
-
- class scoped_lock : boost::noncopyable {
- public:
-#if defined(_DEBUG)
- struct PostStaticCheck {
- PostStaticCheck() {
- if ( StaticObserver::_destroyingStatics ) {
- cout << "trying to lock a mongo::mutex during static shutdown" << endl;
- printStackTrace( cout );
- }
- }
- };
-
- PostStaticCheck _check;
- mongo::mutex * const _mut;
-#endif
- scoped_lock( mongo::mutex &m ) :
-#if defined(_DEBUG)
- _mut(&m),
-#endif
- _l( m.boost() ) {
-#if defined(_DEBUG)
- mutexDebugger.entering(_mut->_name);
-#endif
- }
- ~scoped_lock() {
-#if defined(_DEBUG)
- mutexDebugger.leaving(_mut->_name);
-#endif
- }
- boost::timed_mutex::scoped_lock &boost() { return _l; }
- private:
- boost::timed_mutex::scoped_lock _l;
- };
- private:
- boost::timed_mutex &boost() { return *_m; }
- boost::timed_mutex *_m;
- };
-
- typedef mutex::scoped_lock scoped_lock;
- typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock;
-
- /** The concept with SimpleMutex is that it is a basic lock/unlock with no
- special functionality (such as try and try timeout). Thus it can be
- implemented using OS-specific facilities in all environments (if desired).
- On Windows, the implementation below is faster than boost mutex.
- */
-#if defined(_WIN32)
- class SimpleMutex : boost::noncopyable {
- CRITICAL_SECTION _cs;
- public:
- SimpleMutex(const char *name) { InitializeCriticalSection(&_cs); }
- ~SimpleMutex() { DeleteCriticalSection(&_cs); }
-
- void lock() { EnterCriticalSection(&_cs); }
- void unlock() { LeaveCriticalSection(&_cs); }
-
- class scoped_lock : boost::noncopyable {
- SimpleMutex& _m;
- public:
- scoped_lock( SimpleMutex &m ) : _m(m) { _m.lock(); }
- ~scoped_lock() { _m.unlock(); }
- };
- };
-#else
- class SimpleMutex : boost::noncopyable {
- public:
- SimpleMutex(const char* name) { assert( pthread_mutex_init(&_lock,0) == 0 ); }
- ~SimpleMutex(){
- if ( ! StaticObserver::_destroyingStatics ) {
- assert( pthread_mutex_destroy(&_lock) == 0 );
- }
- }
-
- void lock() { assert( pthread_mutex_lock(&_lock) == 0 ); }
- void unlock() { assert( pthread_mutex_unlock(&_lock) == 0 ); }
-
- class scoped_lock : boost::noncopyable {
- SimpleMutex& _m;
- public:
- scoped_lock( SimpleMutex &m ) : _m(m) { _m.lock(); }
- ~scoped_lock() { _m.unlock(); }
- };
-
- private:
- pthread_mutex_t _lock;
- };
-
-#endif
-
-}
diff --git a/util/concurrency/mvar.h b/util/concurrency/mvar.h
deleted file mode 100644
index 9c7a505b6d5..00000000000
--- a/util/concurrency/mvar.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// mvar.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace mongo {
-
- /* This is based on haskell's MVar synchronization primitive:
- * http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Control-Concurrent-MVar.html
- *
- * It is a thread-safe queue that can hold at most one object.
- * You can also think of it as a box that can be either full or empty.
- */
-
- template <typename T>
- class MVar {
- public:
- enum State {EMPTY=0, FULL};
-
- // create an empty MVar
- MVar()
- : _state(EMPTY)
- {}
-
- // creates a full MVar
- MVar(const T& val)
- : _state(FULL)
- , _value(val)
- {}
-
- // puts val into the MVar and returns true or returns false if full
- // never blocks
- bool tryPut(const T& val) {
- // intentionally repeat test before and after lock
- if (_state == FULL) return false;
- Mutex::scoped_lock lock(_mutex);
- if (_state == FULL) return false;
-
- _state = FULL;
- _value = val;
-
- // unblock threads waiting to 'take'
- _condition.notify_all();
-
- return true;
- }
-
- // puts val into the MVar
- // will block if the MVar is already full
- void put(const T& val) {
- Mutex::scoped_lock lock(_mutex);
- while (!tryPut(val)) {
- // unlocks lock while waiting and relocks before returning
- _condition.wait(lock);
- }
- }
-
- // takes val out of the MVar and returns true or returns false if empty
- // never blocks
- bool tryTake(T& out) {
- // intentionally repeat test before and after lock
- if (_state == EMPTY) return false;
- Mutex::scoped_lock lock(_mutex);
- if (_state == EMPTY) return false;
-
- _state = EMPTY;
- out = _value;
-
- // unblock threads waiting to 'put'
- _condition.notify_all();
-
- return true;
- }
-
- // takes val out of the MVar
- // will block if the MVar is empty
- T take() {
- T ret = T();
-
- Mutex::scoped_lock lock(_mutex);
- while (!tryTake(ret)) {
- // unlocks lock while waiting and relocks before returning
- _condition.wait(lock);
- }
-
- return ret;
- }
-
-
- // Note: this is fast because there is no locking, but state could
- // change before you get a chance to act on it.
- // Mainly useful for sanity checks / asserts.
- State getState() { return _state; }
-
-
- private:
- State _state;
- T _value;
- typedef boost::recursive_mutex Mutex;
- Mutex _mutex;
- boost::condition _condition;
- };
-
-}
diff --git a/util/concurrency/race.h b/util/concurrency/race.h
deleted file mode 100644
index 4644e373cda..00000000000
--- a/util/concurrency/race.h
+++ /dev/null
@@ -1,115 +0,0 @@
-#pragma once
-
-#include "../goodies.h" // printStackTrace
-
-namespace mongo {
-
- /** some self-testing of synchronization and attempts to catch race conditions.
-
- use something like:
-
- CodeBlock myBlock;
-
- void foo() {
- CodeBlock::Within w(myBlock);
- ...
- }
-
- In _DEBUG builds, will (sometimes/maybe) fail if two threads are in the same code block at
- the same time. Also detects and disallows recursion.
- */
-
-#ifdef _WIN32
- typedef unsigned threadId_t;
-#else
- typedef pthread_t threadId_t;
-#endif
-
-
-#if defined(_DEBUG)
-
- namespace race {
-
- class CodePoint {
- public:
- string lastName;
- threadId_t lastTid;
- string file;
- CodePoint(string f) : lastTid(0), file(f) { }
- };
- class Check {
- public:
- Check(CodePoint& p) {
- threadId_t t = GetCurrentThreadId();
- if( p.lastTid == 0 ) {
- p.lastTid = t;
- p.lastName = getThreadName();
- }
- else if( t != p.lastTid ) {
- log() << "\n\n\n\n\nRACE? error assert\n " << p.file << '\n'
- << " " << p.lastName
- << " " << getThreadName() << "\n\n" << endl;
- mongoAbort("racecheck");
- }
- };
- };
-
- }
-
-#define RACECHECK
- // dm TODO - the right code for this file is in a different branch at the moment (merge)
- //#define RACECHECK
- //static race::CodePoint __cp(__FILE__);
- //race::Check __ck(__cp);
-
- class CodeBlock {
- volatile int n;
- threadId_t tid;
- void fail() {
- log() << "synchronization (race condition) failure" << endl;
- printStackTrace();
- ::abort();
- }
- void enter() {
- if( ++n != 1 ) fail();
-#if defined(_WIN32)
- tid = GetCurrentThreadId();
-#endif
- }
- void leave() {
- if( --n != 0 ) fail();
- }
- public:
- CodeBlock() : n(0) { }
-
- class Within {
- CodeBlock& _s;
- public:
- Within(CodeBlock& s) : _s(s) { _s.enter(); }
- ~Within() { _s.leave(); }
- };
-
- void assertWithin() {
- assert( n == 1 );
-#if defined(_WIN32)
- assert( GetCurrentThreadId() == tid );
-#endif
- }
- };
-
-#else
-
-#define RACECHECK
-
- class CodeBlock{
- public:
- class Within {
- public:
- Within(CodeBlock&) { }
- };
- void assertWithin() { }
- };
-
-#endif
-
-} // namespace
diff --git a/util/concurrency/rwlock.h b/util/concurrency/rwlock.h
deleted file mode 100644
index ed5bda07519..00000000000
--- a/util/concurrency/rwlock.h
+++ /dev/null
@@ -1,396 +0,0 @@
-// @file rwlock.h generic reader-writer lock (cross platform support)
-
-/*
- * Copyright (C) 2010 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "mutex.h"
-#include "../time_support.h"
-
-// this requires newer windows versions
-// it works better than sharable_mutex under high contention
-#if defined(_WIN64)
-//#define MONGO_USE_SRW_ON_WINDOWS 1
-#endif
-
-#if !defined(MONGO_USE_SRW_ON_WINDOWS)
-
-#if BOOST_VERSION >= 103500
-# define BOOST_RWLOCK
-#else
-# if defined(_WIN32)
-# error need boost >= 1.35 for windows
-# endif
-# include <pthread.h>
-#endif
-
-#if defined(_WIN32)
-# include "shared_mutex_win.hpp"
-namespace mongo {
- typedef boost::modified_shared_mutex shared_mutex;
-}
-# undef assert
-# define assert MONGO_assert
-#elif defined(BOOST_RWLOCK)
-# include <boost/thread/shared_mutex.hpp>
-# undef assert
-# define assert MONGO_assert
-#endif
-
-#endif
-
-namespace mongo {
-
-#if defined(MONGO_USE_SRW_ON_WINDOWS) && defined(_WIN32)
-
- // Windows RWLock implementation (requires newer versions of windows thus the above macro)
- class RWLock : boost::noncopyable {
- public:
- RWLock(const char *, int lowPriorityWaitMS=0 ) : _lowPriorityWaitMS(lowPriorityWaitMS)
- { InitializeSRWLock(&_lock); }
- ~RWLock() { }
- const char * implType() const { return "WINSRW"; }
- int lowPriorityWaitMS() const { return _lowPriorityWaitMS; }
- void lock() { AcquireSRWLockExclusive(&_lock); }
- void unlock() { ReleaseSRWLockExclusive(&_lock); }
- void lock_shared() { AcquireSRWLockShared(&_lock); }
- void unlock_shared() { ReleaseSRWLockShared(&_lock); }
- bool lock_shared_try( int millis ) {
- if( TryAcquireSRWLockShared(&_lock) )
- return true;
- if( millis == 0 )
- return false;
- unsigned long long end = curTimeMicros64() + millis*1000;
- while( 1 ) {
- Sleep(1);
- if( TryAcquireSRWLockShared(&_lock) )
- return true;
- if( curTimeMicros64() >= end )
- break;
- }
- return false;
- }
- bool lock_try( int millis = 0 ) {
- if( TryAcquireSRWLockExclusive(&_lock) ) // quick check to optimistically avoid calling curTimeMicros64
- return true;
- if( millis == 0 )
- return false;
- unsigned long long end = curTimeMicros64() + millis*1000;
- do {
- Sleep(1);
- if( TryAcquireSRWLockExclusive(&_lock) )
- return true;
- } while( curTimeMicros64() < end );
- return false;
- }
- private:
- SRWLOCK _lock;
- const int _lowPriorityWaitMS;
- };
-
-#elif defined(BOOST_RWLOCK)
-
- // Boost based RWLock implementation
- class RWLock : boost::noncopyable {
- shared_mutex _m;
- const int _lowPriorityWaitMS;
- public:
- const char * const _name;
-
- RWLock(const char *name, int lowPriorityWait=0) : _lowPriorityWaitMS(lowPriorityWait) , _name(name) { }
-
- const char * implType() const { return "boost"; }
-
- int lowPriorityWaitMS() const { return _lowPriorityWaitMS; }
-
- void lock() {
- _m.lock();
- DEV mutexDebugger.entering(_name);
- }
-
- /*void lock() {
- // This sequence gives us the lock semantics we want: specifically that write lock acquisition is
- // greedy EXCEPT when someone already is in upgradable state.
- lockAsUpgradable();
- upgrade();
- DEV mutexDebugger.entering(_name);
- }*/
-
- void unlock() {
- DEV mutexDebugger.leaving(_name);
- _m.unlock();
- }
-
- void lockAsUpgradable() {
- _m.lock_upgrade();
- }
- void unlockFromUpgradable() { // upgradable -> unlocked
- _m.unlock_upgrade();
- }
- void upgrade() { // upgradable -> exclusive lock
- _m.unlock_upgrade_and_lock();
- }
-
- void lock_shared() {
- _m.lock_shared();
- }
- void unlock_shared() {
- _m.unlock_shared();
- }
-
- bool lock_shared_try( int millis ) {
- if( _m.timed_lock_shared( boost::posix_time::milliseconds(millis) ) ) {
- return true;
- }
- return false;
- }
-
- bool lock_try( int millis = 0 ) {
- if( _m.timed_lock( boost::posix_time::milliseconds(millis) ) ) {
- DEV mutexDebugger.entering(_name);
- return true;
- }
- return false;
- }
- };
-
-#else
-
- // Posix RWLock implementation
- class RWLock : boost::noncopyable {
- pthread_rwlock_t _lock;
- const int _lowPriorityWaitMS;
- static void check( int x ) {
- if( MONGO_likely(x == 0) )
- return;
- log() << "pthread rwlock failed: " << x << endl;
- assert( x == 0 );
- }
-
- public:
- const char *_name;
- RWLock(const char *name, int lowPriorityWaitMS=0) : _lowPriorityWaitMS(lowPriorityWaitMS), _name(name)
- {
- check( pthread_rwlock_init( &_lock , 0 ) );
- }
-
- ~RWLock() {
- if ( ! StaticObserver::_destroyingStatics ) {
- wassert( pthread_rwlock_destroy( &_lock ) == 0 ); // wassert as don't want to throw from a destructor
- }
- }
-
- const char * implType() const { return "posix"; }
-
- int lowPriorityWaitMS() const { return _lowPriorityWaitMS; }
-
- void lock() {
- check( pthread_rwlock_wrlock( &_lock ) );
- DEV mutexDebugger.entering(_name);
- }
- void unlock() {
- DEV mutexDebugger.leaving(_name);
- check( pthread_rwlock_unlock( &_lock ) );
- }
-
- void lock_shared() {
- check( pthread_rwlock_rdlock( &_lock ) );
- }
-
- void unlock_shared() {
- check( pthread_rwlock_unlock( &_lock ) );
- }
-
- bool lock_shared_try( int millis ) {
- return _try( millis , false );
- }
-
- bool lock_try( int millis = 0 ) {
- if( _try( millis , true ) ) {
- DEV mutexDebugger.entering(_name);
- return true;
- }
- return false;
- }
-
- bool _try( int millis , bool write ) {
- while ( true ) {
- int x = write ?
- pthread_rwlock_trywrlock( &_lock ) :
- pthread_rwlock_tryrdlock( &_lock );
-
- if ( x <= 0 ) {
- return true;
- }
-
- if ( millis-- <= 0 )
- return false;
-
- if ( x == EBUSY ) {
- sleepmillis(1);
- continue;
- }
- check(x);
- }
-
- return false;
- }
-
- };
-
-#endif
-
- /** throws on failure to acquire in the specified time period. */
- class rwlock_try_write : boost::noncopyable {
- public:
- struct exception { };
- rwlock_try_write(RWLock& l, int millis = 0) : _l(l) {
- if( !l.lock_try(millis) )
- throw exception();
- }
- ~rwlock_try_write() { _l.unlock(); }
- private:
- RWLock& _l;
- };
-
- class rwlock_shared : boost::noncopyable {
- public:
- rwlock_shared(RWLock& rwlock) : _r(rwlock) {_r.lock_shared(); }
- ~rwlock_shared() { _r.unlock_shared(); }
- private:
- RWLock& _r;
- };
-
- /* scoped lock for RWLock */
- class rwlock : boost::noncopyable {
- public:
- /**
- * @param write acquire write lock if true sharable if false
- * @param lowPriority if > 0, will try to get the lock non-greedily for that many ms
- */
- rwlock( const RWLock& lock , bool write, /* bool alreadyHaveLock = false , */int lowPriorityWaitMS = 0 )
- : _lock( (RWLock&)lock ) , _write( write ) {
-
- {
- if ( _write ) {
-
- if ( ! lowPriorityWaitMS && lock.lowPriorityWaitMS() )
- lowPriorityWaitMS = lock.lowPriorityWaitMS();
-
- if ( lowPriorityWaitMS ) {
- bool got = false;
- for ( int i=0; i<lowPriorityWaitMS; i++ ) {
- if ( _lock.lock_try(0) ) {
- got = true;
- break;
- }
-
- int sleep = 1;
- if ( i > ( lowPriorityWaitMS / 20 ) )
- sleep = 10;
- sleepmillis(sleep);
- i += ( sleep - 1 );
- }
- if ( ! got ) {
- log() << "couldn't get lazy rwlock" << endl;
- _lock.lock();
- }
- }
- else {
- _lock.lock();
- }
-
- }
- else {
- _lock.lock_shared();
- }
- }
- }
- ~rwlock() {
- if ( _write )
- _lock.unlock();
- else
- _lock.unlock_shared();
- }
- private:
- RWLock& _lock;
- const bool _write;
- };
-
- /** recursive on shared locks is ok for this implementation */
- class RWLockRecursive : boost::noncopyable {
- ThreadLocalValue<int> _state;
- RWLock _lk;
- friend class Exclusive;
- public:
- /** @param lpwaitms lazy wait */
- RWLockRecursive(const char *name, int lpwaitms) : _lk(name, lpwaitms) { }
-
- void assertExclusivelyLocked() {
- dassert( _state.get() < 0 );
- }
-
- // RWLockRecursive::Exclusive scoped lock
- class Exclusive : boost::noncopyable {
- RWLockRecursive& _r;
- rwlock *_scopedLock;
- public:
- Exclusive(RWLockRecursive& r) : _r(r), _scopedLock(0) {
- int s = _r._state.get();
- dassert( s <= 0 );
- if( s == 0 )
- _scopedLock = new rwlock(_r._lk, true);
- _r._state.set(s-1);
- }
- ~Exclusive() {
- int s = _r._state.get();
- DEV wassert( s < 0 ); // wassert: don't throw from destructors
- _r._state.set(s+1);
- delete _scopedLock;
- }
- };
-
- // RWLockRecursive::Shared scoped lock
- class Shared : boost::noncopyable {
- RWLockRecursive& _r;
- bool _alreadyExclusive;
- public:
- Shared(RWLockRecursive& r) : _r(r) {
- int s = _r._state.get();
- _alreadyExclusive = s < 0;
- if( !_alreadyExclusive ) {
- dassert( s >= 0 ); // -1 would mean exclusive
- if( s == 0 )
- _r._lk.lock_shared();
- _r._state.set(s+1);
- }
- }
- ~Shared() {
- if( _alreadyExclusive ) {
- DEV wassert( _r._state.get() < 0 );
- }
- else {
- int s = _r._state.get() - 1;
- if( s == 0 )
- _r._lk.unlock_shared();
- _r._state.set(s);
- DEV wassert( s >= 0 );
- }
- }
- };
- };
-}
diff --git a/util/concurrency/shared_mutex_win.hpp b/util/concurrency/shared_mutex_win.hpp
deleted file mode 100644
index e850fc6bab4..00000000000
--- a/util/concurrency/shared_mutex_win.hpp
+++ /dev/null
@@ -1,594 +0,0 @@
-#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP_MODIFIED
-#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP_MODIFIED
-
-// (C) Copyright 2006-8 Anthony Williams
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-/* MongoDB :
- Slightly modified boost file to not die above 127 pending writes
- Here is what changed (from boost 1.42.0 shared_mutex.hpp):
- 1,2c1,2
- < #ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
- < #define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
- ---
- > #ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP_MODIFIED
- > #define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP_MODIFIED
- 22c27
- < class shared_mutex:
- ---
- > class modified_shared_mutex:
- 73c78
- < shared_mutex():
- ---
- > modified_shared_mutex():
- 84c89
- < ~shared_mutex()
- ---
- > ~modified_shared_mutex()
- 283a289,290
- > if( new_state.exclusive_waiting == 127 ) // the maximum already!
- > break;
-*/
-
-#include <boost/assert.hpp>
-#include <boost/detail/interlocked.hpp>
-#include <boost/thread/win32/thread_primitives.hpp>
-#include <boost/static_assert.hpp>
-#include <limits.h>
-#include <boost/utility.hpp>
-#include <boost/thread/thread_time.hpp>
-
-#include <boost/config/abi_prefix.hpp>
-
-namespace boost
-{
- class modified_shared_mutex:
- private boost::noncopyable
- {
- private:
- struct state_data
- {
- unsigned shared_count:11,
- shared_waiting:11,
- exclusive:1,
- upgrade:1,
- exclusive_waiting:7,
- exclusive_waiting_blocked:1;
-
- friend bool operator==(state_data const& lhs,state_data const& rhs)
- {
- return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
- }
- };
-
-
- template<typename T>
- T interlocked_compare_exchange(T* target,T new_value,T comparand)
- {
- BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
- long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
- *reinterpret_cast<long*>(&new_value),
- *reinterpret_cast<long*>(&comparand));
- return *reinterpret_cast<T const*>(&res);
- }
-
- state_data state;
- detail::win32::handle semaphores[2];
- detail::win32::handle &unlock_sem;
- detail::win32::handle &exclusive_sem;
- detail::win32::handle upgrade_sem;
-
- void release_waiters(state_data old_state)
- {
- if(old_state.exclusive_waiting)
- {
- BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0);
- }
-
- if(old_state.shared_waiting || old_state.exclusive_waiting)
- {
- BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
- }
- }
-
-
- public:
- modified_shared_mutex():
- unlock_sem(semaphores[0]),
- exclusive_sem(semaphores[1])
- {
- unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
- state_data state_={0};
- state=state_;
- }
-
- ~modified_shared_mutex()
- {
- detail::win32::CloseHandle(upgrade_sem);
- detail::win32::CloseHandle(unlock_sem);
- detail::win32::CloseHandle(exclusive_sem);
- }
-
- bool try_lock_shared()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
- {
- ++new_state.shared_count;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
- }
-
- void lock_shared()
- {
- BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
- }
-
- template<typename TimeDuration>
- bool timed_lock_shared(TimeDuration const & relative_time)
- {
- return timed_lock_shared(get_system_time()+relative_time);
- }
-
- bool timed_lock_shared(boost::system_time const& wait_until)
- {
- for(;;)
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.exclusive || new_state.exclusive_waiting_blocked)
- {
- ++new_state.shared_waiting;
- }
- else
- {
- ++new_state.shared_count;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
-
- if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
- {
- return true;
- }
-
- unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
- if(res==detail::win32::timeout)
- {
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.exclusive || new_state.exclusive_waiting_blocked)
- {
- if(new_state.shared_waiting)
- {
- --new_state.shared_waiting;
- }
- }
- else
- {
- ++new_state.shared_count;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
-
- if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
- {
- return true;
- }
- return false;
- }
-
- BOOST_ASSERT(res==0);
- }
- }
-
- void unlock_shared()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- bool const last_reader=!--new_state.shared_count;
-
- if(last_reader)
- {
- if(new_state.upgrade)
- {
- new_state.upgrade=false;
- new_state.exclusive=true;
- }
- else
- {
- if(new_state.exclusive_waiting)
- {
- --new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=false;
- }
- new_state.shared_waiting=0;
- }
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- if(last_reader)
- {
- if(old_state.upgrade)
- {
- BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
- }
- else
- {
- release_waiters(old_state);
- }
- }
- break;
- }
- old_state=current_state;
- }
- }
-
- void lock()
- {
- BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
- }
-
- template<typename TimeDuration>
- bool timed_lock(TimeDuration const & relative_time)
- {
- return timed_lock(get_system_time()+relative_time);
- }
-
- bool try_lock()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.shared_count || new_state.exclusive)
- {
- return false;
- }
- else
- {
- new_state.exclusive=true;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- return true;
- }
-
-
- bool timed_lock(boost::system_time const& wait_until)
- {
- for(;;)
- {
- state_data old_state=state;
-
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.shared_count || new_state.exclusive)
- {
- if( new_state.exclusive_waiting == 127 ) // the maximum already!
- break;
- ++new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=true;
- }
- else
- {
- new_state.exclusive=true;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
-
- if(!old_state.shared_count && !old_state.exclusive)
- {
- return true;
- }
- unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until));
- if(wait_res==detail::win32::timeout)
- {
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.shared_count || new_state.exclusive)
- {
- if(new_state.exclusive_waiting)
- {
- if(!--new_state.exclusive_waiting)
- {
- new_state.exclusive_waiting_blocked=false;
- }
- }
- }
- else
- {
- new_state.exclusive=true;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- if(!old_state.shared_count && !old_state.exclusive)
- {
- return true;
- }
- return false;
- }
- BOOST_ASSERT(wait_res<2);
- }
- }
-
- void unlock()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- new_state.exclusive=false;
- if(new_state.exclusive_waiting)
- {
- --new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=false;
- }
- new_state.shared_waiting=0;
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- release_waiters(old_state);
- }
-
- void lock_upgrade()
- {
- for(;;)
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
- {
- ++new_state.shared_waiting;
- }
- else
- {
- ++new_state.shared_count;
- new_state.upgrade=true;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
-
- if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
- {
- return;
- }
-
- BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite));
- }
- }
-
- bool try_lock_upgrade()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
- {
- return false;
- }
- else
- {
- ++new_state.shared_count;
- new_state.upgrade=true;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- return true;
- }
-
- void unlock_upgrade()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- new_state.upgrade=false;
- bool const last_reader=!--new_state.shared_count;
-
- if(last_reader)
- {
- if(new_state.exclusive_waiting)
- {
- --new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=false;
- }
- new_state.shared_waiting=0;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- if(last_reader)
- {
- release_waiters(old_state);
- }
- break;
- }
- old_state=current_state;
- }
- }
-
- void unlock_upgrade_and_lock()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- bool const last_reader=!--new_state.shared_count;
-
- if(last_reader)
- {
- new_state.upgrade=false;
- new_state.exclusive=true;
- }
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- if(!last_reader)
- {
- BOOST_VERIFY(!detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite));
- }
- break;
- }
- old_state=current_state;
- }
- }
-
- void unlock_and_lock_upgrade()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- new_state.exclusive=false;
- new_state.upgrade=true;
- ++new_state.shared_count;
- if(new_state.exclusive_waiting)
- {
- --new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=false;
- }
- new_state.shared_waiting=0;
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- release_waiters(old_state);
- }
-
- void unlock_and_lock_shared()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- new_state.exclusive=false;
- ++new_state.shared_count;
- if(new_state.exclusive_waiting)
- {
- --new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=false;
- }
- new_state.shared_waiting=0;
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- release_waiters(old_state);
- }
-
- void unlock_upgrade_and_lock_shared()
- {
- state_data old_state=state;
- for(;;)
- {
- state_data new_state=old_state;
- new_state.upgrade=false;
- if(new_state.exclusive_waiting)
- {
- --new_state.exclusive_waiting;
- new_state.exclusive_waiting_blocked=false;
- }
- new_state.shared_waiting=0;
-
- state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
- if(current_state==old_state)
- {
- break;
- }
- old_state=current_state;
- }
- release_waiters(old_state);
- }
-
- };
-}
-
-#include <boost/config/abi_suffix.hpp>
-
-#endif
diff --git a/util/concurrency/spin_lock.cpp b/util/concurrency/spin_lock.cpp
deleted file mode 100644
index 52bd218dcb6..00000000000
--- a/util/concurrency/spin_lock.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-// spin_lock.cpp
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-#include <time.h>
-#include "spin_lock.h"
-
-namespace mongo {
-
- SpinLock::~SpinLock() {
-#if defined(_WIN32)
- DeleteCriticalSection(&_cs);
-#elif defined(__USE_XOPEN2K)
- pthread_spin_destroy(&_lock);
-#endif
- }
-
- SpinLock::SpinLock()
-#if defined(_WIN32)
- { InitializeCriticalSectionAndSpinCount(&_cs, 4000); }
-#elif defined(__USE_XOPEN2K)
- { pthread_spin_init( &_lock , 0 ); }
-#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
- : _locked( false ) { }
-#else
- : _mutex( "SpinLock" ) { }
-#endif
-
- void SpinLock::lock() {
-#if defined(_WIN32)
- EnterCriticalSection(&_cs);
-#elif defined(__USE_XOPEN2K)
-
- /**
- * this is designed to perform close to the default spin lock
- * the reason for the mild insanity is to prevent horrible performance
- * when contention spikes
- * it allows spinlocks to be used in many more places
- * which is good because even with this change they are about 8x faster on linux
- */
-
- if ( pthread_spin_trylock( &_lock ) == 0 )
- return;
-
- for ( int i=0; i<1000; i++ )
- if ( pthread_spin_trylock( &_lock ) == 0 )
- return;
-
- for ( int i=0; i<1000; i++ ) {
- if ( pthread_spin_trylock( &_lock ) == 0 )
- return;
- pthread_yield();
- }
-
- struct timespec t;
- t.tv_sec = 0;
- t.tv_nsec = 5000000;
-
- while ( pthread_spin_trylock( &_lock ) != 0 ) {
- nanosleep(&t, NULL);
- }
-
-#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
- // fast path
- if (!_locked && !__sync_lock_test_and_set(&_locked, true)) {
- return;
- }
-
- // wait for lock
- int wait = 1000;
- while ((wait-- > 0) && (_locked)) {}
-
- // if failed to grab lock, sleep
- struct timespec t;
- t.tv_sec = 0;
- t.tv_nsec = 5000000;
- while (__sync_lock_test_and_set(&_locked, true)) {
- nanosleep(&t, NULL);
- }
-#else
- // WARNING Missing spin lock in this platform. This can potentially
- // be slow.
- _mutex.lock();
-
-#endif
- }
-
- void SpinLock::unlock() {
-#if defined(_WIN32)
- LeaveCriticalSection(&_cs);
-#elif defined(__USE_XOPEN2K)
- pthread_spin_unlock(&_lock);
-#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
- __sync_lock_release(&_locked);
-#else
- _mutex.unlock();
-#endif
- }
-
- bool SpinLock::isfast() {
-#if defined(_WIN32)
- return true;
-#elif defined(__USE_XOPEN2K)
- return true;
-#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
- return true;
-#else
- return false;
-#endif
- }
-
-
-} // namespace mongo
diff --git a/util/concurrency/spin_lock.h b/util/concurrency/spin_lock.h
deleted file mode 100644
index 65ecb152ddb..00000000000
--- a/util/concurrency/spin_lock.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// spin_lock.h
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "mutex.h"
-
-namespace mongo {
-
- /**
- * The spinlock currently requires late GCC support routines to be efficient.
- * Other platforms default to a mutex implemenation.
- */
- class SpinLock : boost::noncopyable {
- public:
- SpinLock();
- ~SpinLock();
-
- void lock();
- void unlock();
-
- static bool isfast(); // true if a real spinlock on this platform
-
- private:
-#if defined(_WIN32)
- CRITICAL_SECTION _cs;
-#elif defined(__USE_XOPEN2K)
- pthread_spinlock_t _lock;
-#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
- volatile bool _locked;
-#else
- // default to a mutex if not implemented
- SimpleMutex _mutex;
-#endif
- };
-
- class scoped_spinlock : boost::noncopyable {
- public:
- scoped_spinlock( SpinLock& l ) : _l(l) {
- _l.lock();
- }
- ~scoped_spinlock() {
- _l.unlock();}
- private:
- SpinLock& _l;
- };
-
-} // namespace mongo
diff --git a/util/concurrency/synchronization.cpp b/util/concurrency/synchronization.cpp
deleted file mode 100644
index ce2547c25eb..00000000000
--- a/util/concurrency/synchronization.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// synchronization.cpp
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "synchronization.h"
-
-namespace mongo {
-
- Notification::Notification() : _mutex ( "Notification" ) , _notified( false ) {
- }
-
- Notification::~Notification() { }
-
- void Notification::waitToBeNotified() {
- scoped_lock lock( _mutex );
- while ( ! _notified )
- _condition.wait( lock.boost() );
- }
-
- void Notification::notifyOne() {
- scoped_lock lock( _mutex );
- assert( !_notified );
- _notified = true;
- _condition.notify_one();
- }
-
- /* --- NotifyAll --- */
-
- NotifyAll::NotifyAll() : _mutex("NotifyAll") {
- _lastDone = 0;
- _lastReturned = 0;
- _nWaiting = 0;
- }
-
- NotifyAll::When NotifyAll::now() {
- scoped_lock lock( _mutex );
- return ++_lastReturned;
- }
-
- void NotifyAll::waitFor(When e) {
- scoped_lock lock( _mutex );
- ++_nWaiting;
- while( _lastDone < e ) {
- _condition.wait( lock.boost() );
- }
- }
-
- void NotifyAll::awaitBeyondNow() {
- scoped_lock lock( _mutex );
- ++_nWaiting;
- When e = ++_lastReturned;
- while( _lastDone <= e ) {
- _condition.wait( lock.boost() );
- }
- }
-
- void NotifyAll::notifyAll(When e) {
- scoped_lock lock( _mutex );
- _lastDone = e;
- _nWaiting = 0;
- _condition.notify_all();
- }
-
-} // namespace mongo
diff --git a/util/concurrency/synchronization.h b/util/concurrency/synchronization.h
deleted file mode 100644
index a0e89f7246b..00000000000
--- a/util/concurrency/synchronization.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// synchronization.h
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <boost/thread/condition.hpp>
-#include "mutex.h"
-
-namespace mongo {
-
- /*
- * A class to establish a synchronization point between two threads. One thread is the waiter and one is
- * the notifier. After the notification event, both proceed normally.
- *
- * This class is thread-safe.
- */
- class Notification {
- public:
- Notification();
- ~Notification();
-
- /*
- * Blocks until the method 'notifyOne()' is called.
- */
- void waitToBeNotified();
-
- /*
- * Notifies the waiter of '*this' that it can proceed. Can only be called once.
- */
- void notifyOne();
-
- private:
- mongo::mutex _mutex; // protects state below
- bool _notified; // was notifyOne() issued?
- boost::condition _condition; // cond over _notified being true
- };
-
- /** establishes a synchronization point between threads. N threads are waits and one is notifier.
- threadsafe.
- */
- class NotifyAll : boost::noncopyable {
- public:
- NotifyAll();
-
- typedef unsigned long long When;
-
- When now();
-
- /** awaits the next notifyAll() call by another thread. notifications that precede this
- call are ignored -- we are looking for a fresh event.
- */
- void waitFor(When);
-
- /** a bit faster than waitFor( now() ) */
- void awaitBeyondNow();
-
- /** may be called multiple times. notifies all waiters */
- void notifyAll(When);
-
- /** indicates how many threads are waiting for a notify. */
- unsigned nWaiting() const { return _nWaiting; }
-
- private:
- mongo::mutex _mutex;
- boost::condition _condition;
- When _lastDone;
- When _lastReturned;
- unsigned _nWaiting;
- };
-
-} // namespace mongo
diff --git a/util/concurrency/task.cpp b/util/concurrency/task.cpp
deleted file mode 100644
index d84cd71dceb..00000000000
--- a/util/concurrency/task.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-// @file task.cpp
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,b
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-
-#include <boost/thread/condition.hpp>
-
-#include "task.h"
-#include "../goodies.h"
-#include "../unittest.h"
-#include "../time_support.h"
-
-namespace mongo {
-
- namespace task {
-
- /*void foo() {
- boost::mutex m;
- boost::mutex::scoped_lock lk(m);
- boost::condition cond;
- cond.wait(lk);
- cond.notify_one();
- }*/
-
- Task::Task()
- : BackgroundJob( true /* deleteSelf */ ) {
- n = 0;
- repeat = 0;
- }
-
- void Task::halt() { repeat = 0; }
-
- void Task::run() {
- assert( n == 0 );
- while( 1 ) {
- n++;
- try {
- doWork();
- }
- catch(...) { }
- if( repeat == 0 )
- break;
- sleepmillis(repeat);
- if( inShutdown() )
- break;
- }
- }
-
- void Task::begin() {
- go();
- }
-
- void fork(Task *t) {
- t->begin();
- }
-
- void repeat(Task *t, unsigned millis) {
- t->repeat = millis;
- t->begin();
- }
-
- }
-}
-
-#include "msg.h"
-
-/* task::Server */
-
-namespace mongo {
- namespace task {
-
- /* to get back a return value */
- struct Ret {
- Ret() : done(false) { }
- bool done;
- boost::mutex m;
- boost::condition c;
- const lam *msg;
- void f() {
- (*msg)();
- done = true;
- c.notify_one();
- }
- };
-
- void Server::call( const lam& msg ) {
- Ret r;
- r.msg = &msg;
- lam f = boost::bind(&Ret::f, &r);
- send(f);
- {
- boost::mutex::scoped_lock lk(r.m);
- while( !r.done )
- r.c.wait(lk);
- }
- }
-
- void Server::send( lam msg ) {
- {
- boost::mutex::scoped_lock lk(m);
- d.push_back(msg);
- }
- c.notify_one();
- }
-
- void Server::doWork() {
- starting();
- while( 1 ) {
- lam f;
- try {
- boost::mutex::scoped_lock lk(m);
- while( d.empty() )
- c.wait(lk);
- f = d.front();
- d.pop_front();
- }
- catch(...) {
- log() << "ERROR exception in Server:doWork?" << endl;
- }
- try {
- f();
- if( rq ) {
- rq = false;
- {
- boost::mutex::scoped_lock lk(m);
- d.push_back(f);
- }
- }
- }
- catch(std::exception& e) {
- log() << "Server::doWork task:" << name() << " exception:" << e.what() << endl;
- }
- catch(const char *p) {
- log() << "Server::doWork task:" << name() << " unknown c exception:" <<
- ((p&&strlen(p)<800)?p:"?") << endl;
- }
- catch(...) {
- log() << "Server::doWork unknown exception task:" << name() << endl;
- }
- }
- }
-
- static Server *s;
- static void abc(int i) {
- cout << "Hello " << i << endl;
- s->requeue();
- }
- class TaskUnitTest : public mongo::UnitTest {
- public:
- virtual void run() {
- lam f = boost::bind(abc, 3);
- //f();
-
- s = new Server("unittest");
- fork(s);
- s->send(f);
-
- sleepsecs(30);
- cout <<" done" << endl;
-
- }
- }; // not running. taskunittest;
-
- }
-}
diff --git a/util/concurrency/task.h b/util/concurrency/task.h
deleted file mode 100644
index d7b45eeef24..00000000000
--- a/util/concurrency/task.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// @file task.h
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,b
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "../background.h"
-
-namespace mongo {
-
- namespace task {
-
- /** abstraction around threads. simpler than BackgroundJob which is used behind the scenes.
- allocate the Task dynamically. when the thread terminates, the Task object will delete itself.
- */
- class Task : private BackgroundJob {
- protected:
- virtual void doWork() = 0; // implement the task here.
- virtual string name() const = 0; // name the threada
- public:
- Task();
-
- /** for a repeating task, stop after current invocation ends. can be called by other threads
- as long as the Task is still in scope.
- */
- void halt();
- private:
- unsigned n, repeat;
- friend void fork(Task* t);
- friend void repeat(Task* t, unsigned millis);
- virtual void run();
- //virtual void ending() { }
- void begin();
- };
-
- /** run once */
- void fork(Task *t);
-
- /** run doWork() over and over, with a pause between runs of millis */
- void repeat(Task *t, unsigned millis);
-
- /*** Example ***
- inline void sample() {
- class Sample : public Task {
- public:
- int result;
- virtual void doWork() { result = 1234; }
- Sample() : result(0) { }
- };
- shared_ptr<Sample> q( new Sample() );
- fork(q);
- cout << q->result << endl; // could print 1234 or 0.
- }
- */
-
- }
-
-}
diff --git a/util/concurrency/thread_pool.cpp b/util/concurrency/thread_pool.cpp
deleted file mode 100644
index 1c258847cb5..00000000000
--- a/util/concurrency/thread_pool.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/* threadpool.cpp
-*/
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "thread_pool.h"
-#include "mvar.h"
-
-namespace mongo {
- namespace threadpool {
-
- // Worker thread
- class Worker : boost::noncopyable {
- public:
- explicit Worker(ThreadPool& owner)
- : _owner(owner)
- , _is_done(true)
- , _thread(boost::bind(&Worker::loop, this))
- {}
-
- // destructor will block until current operation is completed
- // Acts as a "join" on this thread
- ~Worker() {
- _task.put(Task());
- _thread.join();
- }
-
- void set_task(Task& func) {
- assert(!func.empty());
- assert(_is_done);
- _is_done = false;
-
- _task.put(func);
- }
-
- private:
- ThreadPool& _owner;
- MVar<Task> _task;
- bool _is_done; // only used for error detection
- boost::thread _thread;
-
- void loop() {
- while (true) {
- Task task = _task.take();
- if (task.empty())
- break; // ends the thread
-
- try {
- task();
- }
- catch (std::exception e) {
- log() << "Unhandled exception in worker thread: " << e.what() << endl;;
- }
- catch (...) {
- log() << "Unhandled non-exception in worker thread" << endl;
- }
- _is_done = true;
- _owner.task_done(this);
- }
- }
- };
-
- ThreadPool::ThreadPool(int nThreads)
- : _mutex("ThreadPool"), _tasksRemaining(0)
- , _nThreads(nThreads) {
- scoped_lock lock(_mutex);
- while (nThreads-- > 0) {
- Worker* worker = new Worker(*this);
- _freeWorkers.push_front(worker);
- }
- }
-
- ThreadPool::~ThreadPool() {
- join();
-
- assert(_tasks.empty());
-
- // O(n) but n should be small
- assert(_freeWorkers.size() == (unsigned)_nThreads);
-
- while(!_freeWorkers.empty()) {
- delete _freeWorkers.front();
- _freeWorkers.pop_front();
- }
- }
-
- void ThreadPool::join() {
- scoped_lock lock(_mutex);
- while(_tasksRemaining) {
- _condition.wait(lock.boost());
- }
- }
-
- void ThreadPool::schedule(Task task) {
- scoped_lock lock(_mutex);
-
- _tasksRemaining++;
-
- if (!_freeWorkers.empty()) {
- _freeWorkers.front()->set_task(task);
- _freeWorkers.pop_front();
- }
- else {
- _tasks.push_back(task);
- }
- }
-
- // should only be called by a worker from the worker thread
- void ThreadPool::task_done(Worker* worker) {
- scoped_lock lock(_mutex);
-
- if (!_tasks.empty()) {
- worker->set_task(_tasks.front());
- _tasks.pop_front();
- }
- else {
- _freeWorkers.push_front(worker);
- }
-
- _tasksRemaining--;
-
- if(_tasksRemaining == 0)
- _condition.notify_all();
- }
-
- } //namespace threadpool
-} //namespace mongo
diff --git a/util/concurrency/thread_pool.h b/util/concurrency/thread_pool.h
deleted file mode 100644
index b348ed1d01b..00000000000
--- a/util/concurrency/thread_pool.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// thread_pool.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-#undef assert
-#define assert MONGO_assert
-
-namespace mongo {
-
- namespace threadpool {
- class Worker;
-
- typedef boost::function<void(void)> Task; //nullary function or functor
-
- // exported to the mongo namespace
- class ThreadPool : boost::noncopyable {
- public:
- explicit ThreadPool(int nThreads=8);
-
- // blocks until all tasks are complete (tasks_remaining() == 0)
- // You should not call schedule while in the destructor
- ~ThreadPool();
-
- // blocks until all tasks are complete (tasks_remaining() == 0)
- // does not prevent new tasks from being scheduled so could wait forever.
- // Also, new tasks could be scheduled after this returns.
- void join();
-
- // task will be copied a few times so make sure it's relatively cheap
- void schedule(Task task);
-
- // Helpers that wrap schedule and boost::bind.
- // Functor and args will be copied a few times so make sure it's relatively cheap
- template<typename F, typename A>
- void schedule(F f, A a) { schedule(boost::bind(f,a)); }
- template<typename F, typename A, typename B>
- void schedule(F f, A a, B b) { schedule(boost::bind(f,a,b)); }
- template<typename F, typename A, typename B, typename C>
- void schedule(F f, A a, B b, C c) { schedule(boost::bind(f,a,b,c)); }
- template<typename F, typename A, typename B, typename C, typename D>
- void schedule(F f, A a, B b, C c, D d) { schedule(boost::bind(f,a,b,c,d)); }
- template<typename F, typename A, typename B, typename C, typename D, typename E>
- void schedule(F f, A a, B b, C c, D d, E e) { schedule(boost::bind(f,a,b,c,d,e)); }
-
- int tasks_remaining() { return _tasksRemaining; }
-
- private:
- mongo::mutex _mutex;
- boost::condition _condition;
-
- list<Worker*> _freeWorkers; //used as LIFO stack (always front)
- list<Task> _tasks; //used as FIFO queue (push_back, pop_front)
- int _tasksRemaining; // in queue + currently processing
- int _nThreads; // only used for sanity checking. could be removed in the future.
-
- // should only be called by a worker from the worker's thread
- void task_done(Worker* worker);
- friend class Worker;
- };
-
- } //namespace threadpool
-
- using threadpool::ThreadPool;
-
-} //namespace mongo
diff --git a/util/concurrency/value.h b/util/concurrency/value.h
deleted file mode 100644
index 897fa95af1e..00000000000
--- a/util/concurrency/value.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* @file value.h
- concurrency helpers DiagStr, Guarded
-*/
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,b
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "mutex.h"
-#include "spin_lock.h"
-
-namespace mongo {
-
- /** declare that a variable that is "guarded" by a mutex.
-
- The decl documents the rule. For example "counta and countb are guarded by xyzMutex":
-
- Guarded<int, xyzMutex> counta;
- Guarded<int, xyzMutex> countb;
-
- Upon use, specify the scoped_lock object. This makes it hard for someone
- later to forget to be in the lock. Check is made that it is the right lock in _DEBUG
- builds at runtime.
- */
- template <typename T, mutex& BY>
- class Guarded : boost::noncopyable {
- T _val;
- public:
- T& ref(const scoped_lock& lk) {
- dassert( lk._mut == &BY );
- return _val;
- }
- };
-
- class DiagStr {
- string _s;
- mutable SpinLock m;
- public:
- DiagStr(const DiagStr& r) : _s(r.get()) { }
- DiagStr() { }
- bool empty() const {
- scoped_spinlock lk(m);
- return _s.empty();
- }
- string get() const {
- scoped_spinlock lk(m);
- return _s;
- }
-
- void set(const char *s) {
- scoped_spinlock lk(m);
- _s = s;
- }
- void set(const string& s) {
- scoped_spinlock lk(m);
- _s = s;
- }
- operator string() const { return get(); }
- void operator=(const string& s) { set(s); }
- void operator=(const DiagStr& rhs) {
- scoped_spinlock lk(m);
- _s = rhs.get();
- }
- };
-
-#if 0 // not including in 2.0
-
- /** Thread safe map.
- Be careful not to use this too much or it could make things slow;
- if not a hot code path no problem.
-
- Examples:
-
- mapsf<int,int> mp;
-
- int x = mp.get();
-
- map<int,int> two;
- mp.swap(two);
-
- {
- mapsf<int,int>::ref r(mp);
- r[9] = 1;
- map<int,int>::iterator i = r.r.begin();
- }
-
- */
- template< class K, class V >
- struct mapsf : boost::noncopyable {
- SimpleMutex m;
- map<K,V> val;
- friend struct ref;
- public:
- mapsf() : m("mapsf") { }
- void swap(map<K,V>& rhs) {
- SimpleMutex::scoped_lock lk(m);
- val.swap(rhs);
- }
- // safe as we pass by value:
- V get(K k) {
- SimpleMutex::scoped_lock lk(m);
- map<K,V>::iterator i = val.find(k);
- if( i == val.end() )
- return K();
- return i->second;
- }
- // think about deadlocks when using ref. the other methods
- // above will always be safe as they are "leaf" operations.
- struct ref {
- SimpleMutex::scoped_lock lk;
- public:
- map<K,V> const &r;
- ref(mapsf<K,V> &m) : lk(m.m), r(m.val) { }
- V& operator[](const K& k) { return r[k]; }
- };
- };
-#endif
-}
diff --git a/util/concurrency/vars.cpp b/util/concurrency/vars.cpp
deleted file mode 100644
index b561ccce003..00000000000
--- a/util/concurrency/vars.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// vars.cpp
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,b
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-#include "mutex.h"
-#include "value.h"
-
-namespace mongo {
-
- // intentional leak. otherwise destructor orders can be problematic at termination.
- MutexDebugger &mutexDebugger = *(new MutexDebugger());
-
- MutexDebugger::MutexDebugger() :
- x( *(new boost::mutex()) ), magic(0x12345678) {
- // optional way to debug lock order
- /*
- a = "a_lock";
- b = "b_lock";
- */
- }
-
- void MutexDebugger::programEnding() {
- if( logLevel>=1 && followers.size() ) {
- std::cout << followers.size() << " mutexes in program" << endl;
- for( map< mid, set<mid> >::iterator i = followers.begin(); i != followers.end(); i++ ) {
- cout << i->first;
- if( maxNest[i->first] > 1 )
- cout << " maxNest:" << maxNest[i->first];
- cout << '\n';
- for( set<mid>::iterator j = i->second.begin(); j != i->second.end(); j++ )
- cout << " " << *j << '\n';
- }
- cout.flush();
- }
- }
-
-}
diff --git a/util/debug_util.cpp b/util/debug_util.cpp
deleted file mode 100644
index 8ba6534ef7c..00000000000
--- a/util/debug_util.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// debug_util.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "../db/cmdline.h"
-#include "../db/jsobj.h"
-
-namespace mongo {
-
-#if defined(USE_GDBSERVER)
- /* Magic gdb trampoline
- * Do not call directly! call setupSIGTRAPforGDB()
- * Assumptions:
- * 1) gdbserver is on your path
- * 2) You have run "handle SIGSTOP noprint" in gdb
- * 3) cmdLine.port + 2000 is free
- */
- void launchGDB(int) {
- // Don't come back here
- signal(SIGTRAP, SIG_IGN);
-
- int newPort = cmdLine.port + 2000;
- string newPortStr = "localhost:" + BSONObjBuilder::numStr(newPort);
- string pidToDebug = BSONObjBuilder::numStr(getpid());
-
- cout << "\n\n\t**** Launching gdbserver on " << newPortStr << " ****" << endl << endl;
- if (fork() == 0) {
- //child
- execlp("gdbserver", "gdbserver", "--attach", newPortStr.c_str(), pidToDebug.c_str(), NULL);
- perror(NULL);
- }
- else {
- //parent
- raise(SIGSTOP); // pause all threads until gdb connects and continues
- raise(SIGTRAP); // break inside gdbserver
- }
- }
-
- void setupSIGTRAPforGDB() {
- assert( signal(SIGTRAP , launchGDB ) != SIG_ERR );
- }
-#else
- void setupSIGTRAPforGDB() {
- }
-#endif
-}
diff --git a/util/debug_util.h b/util/debug_util.h
deleted file mode 100644
index abed8d94924..00000000000
--- a/util/debug_util.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// debug_util.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#ifndef _WIN32
-#include <signal.h>
-#endif
-
-namespace mongo {
-
-// for debugging
- typedef struct _Ints {
- int i[100];
- } *Ints;
- typedef struct _Chars {
- char c[200];
- } *Chars;
-
- typedef char CHARS[400];
-
- typedef struct _OWS {
- int size;
- char type;
- char string[400];
- } *OWS;
-
-#if defined(_DEBUG)
- enum {DEBUG_BUILD = 1};
-#else
- enum {DEBUG_BUILD = 0};
-#endif
-
-#define MONGO_DEV if( DEBUG_BUILD )
-#define DEV MONGO_DEV
-
-#define MONGO_DEBUGGING if( 0 )
-#define DEBUGGING MONGO_DEBUGGING
-
-// The following declare one unique counter per enclosing function.
-// NOTE The implementation double-increments on a match, but we don't really care.
-#define MONGO_SOMETIMES( occasion, howOften ) for( static unsigned occasion = 0; ++occasion % howOften == 0; )
-#define SOMETIMES MONGO_SOMETIMES
-
-#define MONGO_OCCASIONALLY SOMETIMES( occasionally, 16 )
-#define OCCASIONALLY MONGO_OCCASIONALLY
-
-#define MONGO_RARELY SOMETIMES( rarely, 128 )
-#define RARELY MONGO_RARELY
-
-#define MONGO_ONCE for( static bool undone = true; undone; undone = false )
-#define ONCE MONGO_ONCE
-
-#if defined(_WIN32)
- inline int strcasecmp(const char* s1, const char* s2) {return _stricmp(s1, s2);}
-#endif
-
- // Sets SIGTRAP handler to launch GDB
- // Noop unless on *NIX and compiled with _DEBUG
- void setupSIGTRAPforGDB();
-
- extern int tlogLevel;
-
- inline void breakpoint() {
- if ( tlogLevel < 0 )
- return;
-#ifdef _WIN32
- //DEV DebugBreak();
-#endif
-#ifndef _WIN32
- // code to raise a breakpoint in GDB
- ONCE {
- //prevent SIGTRAP from crashing the program if default action is specified and we are not in gdb
- struct sigaction current;
- sigaction(SIGTRAP, NULL, &current);
- if (current.sa_handler == SIG_DFL) {
- signal(SIGTRAP, SIG_IGN);
- }
- }
-
- raise(SIGTRAP);
-#endif
- }
-
-
- // conditional breakpoint
- inline void breakif(bool test) {
- if (test)
- breakpoint();
- }
-
-} // namespace mongo
diff --git a/util/embedded_builder.h b/util/embedded_builder.h
deleted file mode 100644
index abf518e2583..00000000000
--- a/util/embedded_builder.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// embedded_builder.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
-
- // utility class for assembling hierarchical objects
- class EmbeddedBuilder {
- public:
- EmbeddedBuilder( BSONObjBuilder *b ) {
- _builders.push_back( make_pair( "", b ) );
- }
- // It is assumed that the calls to prepareContext will be made with the 'name'
- // parameter in lex ascending order.
- void prepareContext( string &name ) {
- int i = 1, n = _builders.size();
- while( i < n &&
- name.substr( 0, _builders[ i ].first.length() ) == _builders[ i ].first &&
- ( name[ _builders[i].first.length() ] == '.' || name[ _builders[i].first.length() ] == 0 )
- ) {
- name = name.substr( _builders[ i ].first.length() + 1 );
- ++i;
- }
- for( int j = n - 1; j >= i; --j ) {
- popBuilder();
- }
- for( string next = splitDot( name ); !next.empty(); next = splitDot( name ) ) {
- addBuilder( next );
- }
- }
- void appendAs( const BSONElement &e, string name ) {
- if ( e.type() == Object && e.valuesize() == 5 ) { // empty object -- this way we can add to it later
- string dummyName = name + ".foo";
- prepareContext( dummyName );
- return;
- }
- prepareContext( name );
- back()->appendAs( e, name );
- }
- BufBuilder &subarrayStartAs( string name ) {
- prepareContext( name );
- return back()->subarrayStart( name );
- }
- void done() {
- while( ! _builderStorage.empty() )
- popBuilder();
- }
-
- static string splitDot( string & str ) {
- size_t pos = str.find( '.' );
- if ( pos == string::npos )
- return "";
- string ret = str.substr( 0, pos );
- str = str.substr( pos + 1 );
- return ret;
- }
-
- private:
- void addBuilder( const string &name ) {
- shared_ptr< BSONObjBuilder > newBuilder( new BSONObjBuilder( back()->subobjStart( name ) ) );
- _builders.push_back( make_pair( name, newBuilder.get() ) );
- _builderStorage.push_back( newBuilder );
- }
- void popBuilder() {
- back()->done();
- _builders.pop_back();
- _builderStorage.pop_back();
- }
-
- BSONObjBuilder *back() { return _builders.back().second; }
-
- vector< pair< string, BSONObjBuilder * > > _builders;
- vector< shared_ptr< BSONObjBuilder > > _builderStorage;
-
- };
-
-} //namespace mongo
diff --git a/util/file.h b/util/file.h
deleted file mode 100644
index 368e6927b43..00000000000
--- a/util/file.h
+++ /dev/null
@@ -1,230 +0,0 @@
-// file.h cross platform basic file class. supports 64 bit offsets and such.
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#if !defined(_WIN32)
-#include "errno.h"
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/statvfs.h>
-#endif
-#include "text.h"
-
-namespace mongo {
-
-#ifndef __sunos__
- typedef uint64_t fileofs;
-#else
- typedef boost::uint64_t fileofs;
-#endif
-
- /* NOTE: not thread-safe. (at least the windows implementation isn't. */
-
- class FileInterface {
- public:
- void open(const char *fn) {}
- void write(fileofs o, const char *data, unsigned len) {}
- void read(fileofs o, char *data, unsigned len) {}
- bool bad() {return false;}
- bool is_open() {return false;}
- fileofs len() { return 0; }
- void fsync() { assert(false); }
-
- // shrink file to size bytes. No-op if file already smaller.
- void truncate(fileofs size);
-
- /** @return -1 if error or unavailable */
- static boost::intmax_t freeSpace(const string &path) { assert(false); return -1; }
- };
-
-#if defined(_WIN32)
-#include <io.h>
-
- class File : public FileInterface {
- HANDLE fd;
- bool _bad;
- string _name;
- void err(BOOL b=false) { /* false = error happened */
- if( !b && !_bad ) {
- _bad = true;
- log() << "File " << _name << "I/O error " << GetLastError() << '\n';
- }
- }
- public:
- File() {
- fd = INVALID_HANDLE_VALUE;
- _bad = true;
- }
- ~File() {
- if( is_open() ) CloseHandle(fd);
- fd = INVALID_HANDLE_VALUE;
- }
- void open(const char *filename, bool readOnly=false , bool direct=false) {
- _name = filename;
- fd = CreateFile(
- toNativeString(filename).c_str(),
- ( readOnly ? 0 : GENERIC_WRITE ) | GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if( !is_open() ) {
- DWORD e = GetLastError();
- log() << "Create/Open File failed " << filename << ' ' << errnoWithDescription(e) << endl;
- }
- else
- _bad = false;
- }
- static boost::intmax_t freeSpace(const string &path) {
- ULARGE_INTEGER avail;
- if( GetDiskFreeSpaceEx(toNativeString(path.c_str()).c_str(), &avail, NULL, NULL) ) {
- return avail.QuadPart;
- }
- DWORD e = GetLastError();
- log() << "GetDiskFreeSpaceEx fails errno: " << e << endl;
- return -1;
- }
- void write(fileofs o, const char *data, unsigned len) {
- LARGE_INTEGER li;
- li.QuadPart = o;
- SetFilePointerEx(fd, li, NULL, FILE_BEGIN);
- DWORD written;
- err( WriteFile(fd, data, len, &written, NULL) );
- }
- void read(fileofs o, char *data, unsigned len) {
- DWORD read;
- LARGE_INTEGER li;
- li.QuadPart = o;
- SetFilePointerEx(fd, li, NULL, FILE_BEGIN);
- int ok = ReadFile(fd, data, len, &read, 0);
- if( !ok )
- err(ok);
- else
- massert( 10438 , "ReadFile error - truncated file?", read == len);
- }
- bool bad() { return _bad; }
- bool is_open() { return fd != INVALID_HANDLE_VALUE; }
- fileofs len() {
- LARGE_INTEGER li;
- li.LowPart = GetFileSize(fd, (DWORD *) &li.HighPart);
- if( li.HighPart == 0 && li.LowPart == INVALID_FILE_SIZE ) {
- err( false );
- return 0;
- }
- return li.QuadPart;
- }
- void fsync() { FlushFileBuffers(fd); }
-
- void truncate(fileofs size) {
- if (len() <= size)
- return;
-
- LARGE_INTEGER li;
- li.QuadPart = size;
- if (SetFilePointerEx(fd, li, NULL, FILE_BEGIN) == 0){
- err(false);
- return; //couldn't seek
- }
-
- err(SetEndOfFile(fd));
- }
- };
-
-#else
-
- class File : public FileInterface {
- public:
- int fd;
- private:
- bool _bad;
- void err(bool ok) {
- if( !ok && !_bad ) {
- _bad = true;
- log() << "File I/O " << errnoWithDescription() << '\n';
- }
- }
- public:
- File() {
- fd = -1;
- _bad = true;
- }
- ~File() {
- if( is_open() ) ::close(fd);
- fd = -1;
- }
-
-#ifndef O_NOATIME
-#define O_NOATIME 0
-#endif
-
- void open(const char *filename, bool readOnly=false , bool direct=false) {
- fd = ::open(filename,
- O_CREAT | ( readOnly ? 0 : ( O_RDWR | O_NOATIME ) )
-#if defined(O_DIRECT)
- | ( direct ? O_DIRECT : 0 )
-#endif
- ,
- S_IRUSR | S_IWUSR);
- if ( fd <= 0 ) {
- out() << "couldn't open " << filename << ' ' << errnoWithDescription() << endl;
- return;
- }
- _bad = false;
- }
- void write(fileofs o, const char *data, unsigned len) {
- err( ::pwrite(fd, data, len, o) == (int) len );
- }
- void read(fileofs o, char *data, unsigned len) {
- ssize_t s = ::pread(fd, data, len, o);
- if( s == -1 ) {
- err(false);
- }
- else if( s != (int) len ) {
- _bad = true;
- log() << "File error read:" << s << " bytes, wanted:" << len << " ofs:" << o << endl;
- }
- }
- bool bad() { return _bad; }
- bool is_open() { return fd > 0; }
- fileofs len() {
- off_t o = lseek(fd, 0, SEEK_END);
- if( o != (off_t) -1 )
- return o;
- err(false);
- return 0;
- }
- void fsync() { ::fsync(fd); }
- static boost::intmax_t freeSpace ( const string &path ) {
- struct statvfs info;
- assert( !statvfs( path.c_str() , &info ) );
- return boost::intmax_t( info.f_bavail ) * info.f_frsize;
- }
-
- void truncate(fileofs size) {
- if (len() <= size)
- return;
-
- err(ftruncate(fd, size) == 0);
- }
- };
-
-
-#endif
-
-
-}
-
diff --git a/util/file_allocator.cpp b/util/file_allocator.cpp
deleted file mode 100644
index b0572f971bd..00000000000
--- a/util/file_allocator.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-// @file file_allocator.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include <fcntl.h>
-#include <errno.h>
-
-#if defined(__freebsd__) || defined(__openbsd__)
-#include <sys/stat.h>
-#endif
-
-#include "timer.h"
-#include "mongoutils/str.h"
-using namespace mongoutils;
-
-#ifndef O_NOATIME
-#define O_NOATIME (0)
-#endif
-
-#include "file_allocator.h"
-#include "paths.h"
-
-namespace mongo {
-
- boost::filesystem::path ensureParentDirCreated(const boost::filesystem::path& p){
- const boost::filesystem::path parent = p.branch_path();
-
- if (! boost::filesystem::exists(parent)){
- ensureParentDirCreated(parent);
- log() << "creating directory " << parent.string() << endl;
- boost::filesystem::create_directory(parent);
- flushMyDirectory(parent); // flushes grandparent to ensure parent exists after crash
- }
-
- assert(boost::filesystem::is_directory(parent));
- return parent;
- }
-
-#if defined(_WIN32)
- FileAllocator::FileAllocator() {
- }
-
- void FileAllocator::start() {
- }
-
- void FileAllocator::requestAllocation( const string &name, long &size ) {
- /* Some of the system calls in the file allocator don't work in win,
- so no win support - 32 or 64 bit. Plus we don't seem to need preallocation
- on windows anyway as we don't have to pre-zero the file there.
- */
- }
-
- void FileAllocator::allocateAsap( const string &name, unsigned long long &size ) {
- // no-op
- }
-
- void FileAllocator::waitUntilFinished() const {
- // no-op
- }
-
- void FileAllocator::ensureLength(int fd , long size) {
- // we don't zero on windows
- // TODO : we should to avoid fragmentation
- }
-
- bool FileAllocator::hasFailed() const {
- return false;
- }
-
-#else
-
- FileAllocator::FileAllocator()
- : _pendingMutex("FileAllocator"), _failed() {
- }
-
-
- void FileAllocator::start() {
- boost::thread t( boost::bind( &FileAllocator::run , this ) );
- }
-
- void FileAllocator::requestAllocation( const string &name, long &size ) {
- scoped_lock lk( _pendingMutex );
- if ( _failed )
- return;
- long oldSize = prevSize( name );
- if ( oldSize != -1 ) {
- size = oldSize;
- return;
- }
- _pending.push_back( name );
- _pendingSize[ name ] = size;
- _pendingUpdated.notify_all();
- }
-
- void FileAllocator::allocateAsap( const string &name, unsigned long long &size ) {
- scoped_lock lk( _pendingMutex );
- long oldSize = prevSize( name );
- if ( oldSize != -1 ) {
- size = oldSize;
- if ( !inProgress( name ) )
- return;
- }
- checkFailure();
- _pendingSize[ name ] = size;
- if ( _pending.size() == 0 )
- _pending.push_back( name );
- else if ( _pending.front() != name ) {
- _pending.remove( name );
- list< string >::iterator i = _pending.begin();
- ++i;
- _pending.insert( i, name );
- }
- _pendingUpdated.notify_all();
- while( inProgress( name ) ) {
- checkFailure();
- _pendingUpdated.wait( lk.boost() );
- }
-
- }
-
- void FileAllocator::waitUntilFinished() const {
- if ( _failed )
- return;
- scoped_lock lk( _pendingMutex );
- while( _pending.size() != 0 )
- _pendingUpdated.wait( lk.boost() );
- }
-
- void FileAllocator::ensureLength(int fd , long size) {
-#if defined(__linux__)
- int ret = posix_fallocate(fd,0,size);
- if ( ret == 0 )
- return;
-
- log() << "FileAllocator: posix_fallocate failed: " << errnoWithDescription( ret ) << " falling back" << endl;
-#endif
-
- off_t filelen = lseek(fd, 0, SEEK_END);
- if ( filelen < size ) {
- if (filelen != 0) {
- stringstream ss;
- ss << "failure creating new datafile; lseek failed for fd " << fd << " with errno: " << errnoWithDescription();
- uassert( 10440 , ss.str(), filelen == 0 );
- }
- // Check for end of disk.
-
- uassert( 10441 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(),
- size - 1 == lseek(fd, size - 1, SEEK_SET) );
- uassert( 10442 , str::stream() << "Unable to allocate new file of size " << size << ' ' << errnoWithDescription(),
- 1 == write(fd, "", 1) );
- lseek(fd, 0, SEEK_SET);
-
- const long z = 256 * 1024;
- const boost::scoped_array<char> buf_holder (new char[z]);
- char* buf = buf_holder.get();
- memset(buf, 0, z);
- long left = size;
- while ( left > 0 ) {
- long towrite = left;
- if ( towrite > z )
- towrite = z;
-
- int written = write( fd , buf , towrite );
- uassert( 10443 , errnoWithPrefix("FileAllocator: file write failed" ), written > 0 );
- left -= written;
- }
- }
- }
-
- bool FileAllocator::hasFailed() const {
- return _failed;
- }
-
- void FileAllocator::checkFailure() {
- if (_failed) {
- // we want to log the problem (diskfull.js expects it) but we do not want to dump a stack tracke
- msgassertedNoTrace( 12520, "new file allocation failure" );
- }
- }
-
- long FileAllocator::prevSize( const string &name ) const {
- if ( _pendingSize.count( name ) > 0 )
- return _pendingSize[ name ];
- if ( boost::filesystem::exists( name ) )
- return boost::filesystem::file_size( name );
- return -1;
- }
-
- // caller must hold _pendingMutex lock.
- bool FileAllocator::inProgress( const string &name ) const {
- for( list< string >::const_iterator i = _pending.begin(); i != _pending.end(); ++i )
- if ( *i == name )
- return true;
- return false;
- }
-
- string makeTempFileName( path root ) {
- while( 1 ) {
- path p = root / "_tmp";
- stringstream ss;
- ss << (unsigned) rand();
- p /= ss.str();
- string fn = p.string();
- if( !boost::filesystem::exists(p) )
- return fn;
- }
- return "";
- }
-
- void FileAllocator::run( FileAllocator * fa ) {
- setThreadName( "FileAllocator" );
- while( 1 ) {
- {
- scoped_lock lk( fa->_pendingMutex );
- if ( fa->_pending.size() == 0 )
- fa->_pendingUpdated.wait( lk.boost() );
- }
- while( 1 ) {
- string name;
- long size;
- {
- scoped_lock lk( fa->_pendingMutex );
- if ( fa->_pending.size() == 0 )
- break;
- name = fa->_pending.front();
- size = fa->_pendingSize[ name ];
- }
-
- string tmp;
- long fd = 0;
- try {
- log() << "allocating new datafile " << name << ", filling with zeroes..." << endl;
-
- boost::filesystem::path parent = ensureParentDirCreated(name);
- tmp = makeTempFileName( parent );
- ensureParentDirCreated(tmp);
-
- fd = open(tmp.c_str(), O_CREAT | O_RDWR | O_NOATIME, S_IRUSR | S_IWUSR);
- if ( fd <= 0 ) {
- log() << "FileAllocator: couldn't create " << name << " (" << tmp << ") " << errnoWithDescription() << endl;
- uasserted(10439, "");
- }
-
-#if defined(POSIX_FADV_DONTNEED)
- if( posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED) ) {
- log() << "warning: posix_fadvise fails " << name << " (" << tmp << ") " << errnoWithDescription() << endl;
- }
-#endif
-
- Timer t;
-
- /* make sure the file is the full desired length */
- ensureLength( fd , size );
-
- close( fd );
- fd = 0;
-
- if( rename(tmp.c_str(), name.c_str()) ) {
- log() << "error: couldn't rename " << tmp << " to " << name << ' ' << errnoWithDescription() << endl;
- uasserted(13653, "");
- }
- flushMyDirectory(name);
-
- log() << "done allocating datafile " << name << ", "
- << "size: " << size/1024/1024 << "MB, "
- << " took " << ((double)t.millis())/1000.0 << " secs"
- << endl;
-
- // no longer in a failed state. allow new writers.
- fa->_failed = false;
- }
- catch ( ... ) {
- if ( fd > 0 )
- close( fd );
- log() << "error failed to allocate new file: " << name
- << " size: " << size << ' ' << errnoWithDescription() << warnings;
- log() << " will try again in 10 seconds" << endl; // not going to warning logs
- try {
- if ( tmp.size() )
- BOOST_CHECK_EXCEPTION( boost::filesystem::remove( tmp ) );
- BOOST_CHECK_EXCEPTION( boost::filesystem::remove( name ) );
- }
- catch ( ... ) {
- }
- scoped_lock lk( fa->_pendingMutex );
- fa->_failed = true;
- // not erasing from pending
- fa->_pendingUpdated.notify_all();
-
-
- sleepsecs(10);
- continue;
- }
-
- {
- scoped_lock lk( fa->_pendingMutex );
- fa->_pendingSize.erase( name );
- fa->_pending.pop_front();
- fa->_pendingUpdated.notify_all();
- }
- }
- }
- }
-
-#endif
-
- FileAllocator* FileAllocator::_instance = 0;
-
- FileAllocator* FileAllocator::get(){
- if ( ! _instance )
- _instance = new FileAllocator();
- return _instance;
- }
-
-} // namespace mongo
diff --git a/util/file_allocator.h b/util/file_allocator.h
deleted file mode 100644
index 7c3cacb2888..00000000000
--- a/util/file_allocator.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// @file file_allocator.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../pch.h"
-
-namespace mongo {
-
- /*
- * Handles allocation of contiguous files on disk. Allocation may be
- * requested asynchronously or synchronously.
- * singleton
- */
- class FileAllocator : boost::noncopyable {
- /*
- * The public functions may not be called concurrently. The allocation
- * functions may be called multiple times per file, but only the first
- * size specified per file will be used.
- */
- public:
- void start();
-
- /**
- * May be called if file exists. If file exists, or its allocation has
- * been requested, size is updated to match existing file size.
- */
- void requestAllocation( const string &name, long &size );
-
-
- /**
- * Returns when file has been allocated. If file exists, size is
- * updated to match existing file size.
- */
- void allocateAsap( const string &name, unsigned long long &size );
-
- void waitUntilFinished() const;
-
- bool hasFailed() const;
-
- static void ensureLength(int fd , long size);
-
- /** @return the singletone */
- static FileAllocator * get();
-
- private:
-
- FileAllocator();
-
-#if !defined(_WIN32)
- void checkFailure();
-
- // caller must hold pendingMutex_ lock. Returns size if allocated or
- // allocation requested, -1 otherwise.
- long prevSize( const string &name ) const;
-
- // caller must hold pendingMutex_ lock.
- bool inProgress( const string &name ) const;
-
- /** called from the worked thread */
- static void run( FileAllocator * fa );
-
- mutable mongo::mutex _pendingMutex;
- mutable boost::condition _pendingUpdated;
-
- list< string > _pending;
- mutable map< string, long > _pendingSize;
-
- bool _failed;
-#endif
-
- static FileAllocator* _instance;
-
- };
-
- /** like "mkdir -p" but on parent dir of p rather than p itself */
- boost::filesystem::path ensureParentDirCreated(const boost::filesystem::path& p);
-
-} // namespace mongo
diff --git a/util/goodies.h b/util/goodies.h
deleted file mode 100644
index 735aa8be7ce..00000000000
--- a/util/goodies.h
+++ /dev/null
@@ -1,508 +0,0 @@
-// @file goodies.h
-// miscellaneous
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../bson/util/misc.h"
-#include "concurrency/mutex.h"
-
-namespace mongo {
-
- /* @return a dump of the buffer as hex byte ascii output */
- string hexdump(const char *data, unsigned len);
-
- /**
- * @return if this name has an increasing counter associated, return the value
- * otherwise 0
- */
- unsigned setThreadName(const char * name);
- string getThreadName();
-
- template<class T>
- inline string ToString(const T& t) {
- stringstream s;
- s << t;
- return s.str();
- }
-
-#if !defined(_WIN32) && !defined(NOEXECINFO) && !defined(__freebsd__) && !defined(__openbsd__) && !defined(__sun__)
-
-} // namespace mongo
-
-#include <pthread.h>
-#include <execinfo.h>
-
-namespace mongo {
-
- inline pthread_t GetCurrentThreadId() {
- return pthread_self();
- }
-
- /* use "addr2line -CFe <exe>" to parse. */
- inline void printStackTrace( ostream &o = cout ) {
- void *b[20];
-
- int size = backtrace(b, 20);
- for (int i = 0; i < size; i++)
- o << hex << b[i] << dec << ' ';
- o << endl;
-
- char **strings;
-
- strings = backtrace_symbols(b, size);
- for (int i = 0; i < size; i++)
- o << ' ' << strings[i] << '\n';
- o.flush();
- free (strings);
- }
-#else
- inline void printStackTrace( ostream &o = cout ) { }
-#endif
-
- bool isPrime(int n);
- int nextPrime(int n);
-
- inline void dumpmemory(const char *data, int len) {
- if ( len > 1024 )
- len = 1024;
- try {
- const char *q = data;
- const char *p = q;
- while ( len > 0 ) {
- for ( int i = 0; i < 16; i++ ) {
- if ( *p >= 32 && *p <= 126 )
- cout << *p;
- else
- cout << '.';
- p++;
- }
- cout << " ";
- p -= 16;
- for ( int i = 0; i < 16; i++ )
- cout << (unsigned) ((unsigned char)*p++) << ' ';
- cout << endl;
- len -= 16;
- }
- }
- catch (...) {
- }
- }
-
-// PRINT(2+2); prints "2+2: 4"
-#define MONGO_PRINT(x) cout << #x ": " << (x) << endl
-#define PRINT MONGO_PRINT
-// PRINTFL; prints file:line
-#define MONGO_PRINTFL cout << __FILE__ ":" << __LINE__ << endl
-#define PRINTFL MONGO_PRINTFL
-#define MONGO_FLOG log() << __FILE__ ":" << __LINE__ << endl
-#define FLOG MONGO_FLOG
-
-#undef assert
-#define assert MONGO_assert
-
- inline bool startsWith(const char *str, const char *prefix) {
- size_t l = strlen(prefix);
- if ( strlen(str) < l ) return false;
- return strncmp(str, prefix, l) == 0;
- }
- inline bool startsWith(string s, string p) { return startsWith(s.c_str(), p.c_str()); }
-
- inline bool endsWith(const char *p, const char *suffix) {
- size_t a = strlen(p);
- size_t b = strlen(suffix);
- if ( b > a ) return false;
- return strcmp(p + a - b, suffix) == 0;
- }
-
- inline unsigned long swapEndian(unsigned long x) {
- return
- ((x & 0xff) << 24) |
- ((x & 0xff00) << 8) |
- ((x & 0xff0000) >> 8) |
- ((x & 0xff000000) >> 24);
- }
-
-#if defined(BOOST_LITTLE_ENDIAN)
- inline unsigned long fixEndian(unsigned long x) {
- return x;
- }
-#else
- inline unsigned long fixEndian(unsigned long x) {
- return swapEndian(x);
- }
-#endif
-
-#if !defined(_WIN32)
- typedef int HANDLE;
- inline void strcpy_s(char *dst, unsigned len, const char *src) {
- assert( strlen(src) < len );
- strcpy(dst, src);
- }
-#else
- typedef void *HANDLE;
-#endif
-
- /* thread local "value" rather than a pointer
- good for things which have copy constructors (and the copy constructor is fast enough)
- e.g.
- ThreadLocalValue<int> myint;
- */
- template<class T>
- class ThreadLocalValue {
- public:
- ThreadLocalValue( T def = 0 ) : _default( def ) { }
-
- T get() const {
- T * val = _val.get();
- if ( val )
- return *val;
- return _default;
- }
-
- void set( const T& i ) {
- T *v = _val.get();
- if( v ) {
- *v = i;
- return;
- }
- v = new T(i);
- _val.reset( v );
- }
-
- private:
- boost::thread_specific_ptr<T> _val;
- const T _default;
- };
-
- class ProgressMeter : boost::noncopyable {
- public:
- ProgressMeter( unsigned long long total , int secondsBetween = 3 , int checkInterval = 100 ) {
- reset( total , secondsBetween , checkInterval );
- }
-
- ProgressMeter() {
- _active = 0;
- }
-
- // typically you do ProgressMeterHolder
- void reset( unsigned long long total , int secondsBetween = 3 , int checkInterval = 100 ) {
- _total = total;
- _secondsBetween = secondsBetween;
- _checkInterval = checkInterval;
-
- _done = 0;
- _hits = 0;
- _lastTime = (int)time(0);
-
- _active = 1;
- }
-
- void finished() {
- _active = 0;
- }
-
- bool isActive() {
- return _active;
- }
-
- /**
- * @param n how far along we are relative to the total # we set in CurOp::setMessage
- * @return if row was printed
- */
- bool hit( int n = 1 ) {
- if ( ! _active ) {
- cout << "warning: hit on in-active ProgressMeter" << endl;
- return false;
- }
-
- _done += n;
- _hits++;
- if ( _hits % _checkInterval )
- return false;
-
- int t = (int) time(0);
- if ( t - _lastTime < _secondsBetween )
- return false;
-
- if ( _total > 0 ) {
- int per = (int)( ( (double)_done * 100.0 ) / (double)_total );
- cout << "\t\t" << _done << "/" << _total << "\t" << per << "%" << endl;
- }
- _lastTime = t;
- return true;
- }
-
- void setTotalWhileRunning( unsigned long long total ) {
- _total = total;
- }
-
- unsigned long long done() const { return _done; }
-
- unsigned long long hits() const { return _hits; }
-
- unsigned long long total() const { return _total; }
-
- string toString() const {
- if ( ! _active )
- return "";
- stringstream buf;
- buf << _done << "/" << _total << " " << (_done*100)/_total << "%";
- return buf.str();
- }
-
- bool operator==( const ProgressMeter& other ) const {
- return this == &other;
- }
- private:
-
- bool _active;
-
- unsigned long long _total;
- int _secondsBetween;
- int _checkInterval;
-
- unsigned long long _done;
- unsigned long long _hits;
- int _lastTime;
- };
-
- // e.g.:
- // CurOp * op = cc().curop();
- // ProgressMeterHolder pm( op->setMessage( "index: (1/3) external sort" , d->stats.nrecords , 10 ) );
- // loop { pm.hit(); }
- class ProgressMeterHolder : boost::noncopyable {
- public:
- ProgressMeterHolder( ProgressMeter& pm )
- : _pm( pm ) {
- }
-
- ~ProgressMeterHolder() {
- _pm.finished();
- }
-
- ProgressMeter* operator->() {
- return &_pm;
- }
-
- bool hit( int n = 1 ) {
- return _pm.hit( n );
- }
-
- void finished() {
- _pm.finished();
- }
-
- bool operator==( const ProgressMeter& other ) {
- return _pm == other;
- }
-
- private:
- ProgressMeter& _pm;
- };
-
- class TicketHolder {
- public:
- TicketHolder( int num ) : _mutex("TicketHolder") {
- _outof = num;
- _num = num;
- }
-
- bool tryAcquire() {
- scoped_lock lk( _mutex );
- return _tryAcquire();
- }
-
- void waitForTicket() {
- scoped_lock lk( _mutex );
-
- while( ! _tryAcquire() ) {
- _newTicket.wait( lk.boost() );
- }
- }
-
- void release() {
- {
- scoped_lock lk( _mutex );
- _num++;
- }
- _newTicket.notify_one();
- }
-
- void resize( int newSize ) {
- {
- scoped_lock lk( _mutex );
-
- int used = _outof - _num;
- if ( used > newSize ) {
- cout << "ERROR: can't resize since we're using (" << used << ") more than newSize(" << newSize << ")" << endl;
- return;
- }
-
- _outof = newSize;
- _num = _outof - used;
- }
-
- // Potentially wasteful, but easier to see is correct
- _newTicket.notify_all();
- }
-
- int available() const {
- return _num;
- }
-
- int used() const {
- return _outof - _num;
- }
-
- int outof() const { return _outof; }
-
- private:
-
- bool _tryAcquire(){
- if ( _num <= 0 ) {
- if ( _num < 0 ) {
- cerr << "DISASTER! in TicketHolder" << endl;
- }
- return false;
- }
- _num--;
- return true;
- }
-
- int _outof;
- int _num;
- mongo::mutex _mutex;
- boost::condition_variable_any _newTicket;
- };
-
- class TicketHolderReleaser {
- public:
- TicketHolderReleaser( TicketHolder * holder ) {
- _holder = holder;
- }
-
- ~TicketHolderReleaser() {
- _holder->release();
- }
- private:
- TicketHolder * _holder;
- };
-
-
- /**
- * this is a thread safe string
- * you will never get a bad pointer, though data may be mungedd
- */
- class ThreadSafeString {
- public:
- ThreadSafeString( size_t size=256 )
- : _size( size ) , _buf( new char[size] ) {
- memset( _buf , 0 , _size );
- }
-
- ThreadSafeString( const ThreadSafeString& other )
- : _size( other._size ) , _buf( new char[_size] ) {
- strncpy( _buf , other._buf , _size );
- }
-
- ~ThreadSafeString() {
- delete[] _buf;
- _buf = 0;
- }
-
- string toString() const {
- string s = _buf;
- return s;
- }
-
- ThreadSafeString& operator=( const char * str ) {
- size_t s = strlen(str);
- if ( s >= _size - 2 )
- s = _size - 2;
- strncpy( _buf , str , s );
- _buf[s] = 0;
- return *this;
- }
-
- bool operator==( const ThreadSafeString& other ) const {
- return strcmp( _buf , other._buf ) == 0;
- }
-
- bool operator==( const char * str ) const {
- return strcmp( _buf , str ) == 0;
- }
-
- bool operator!=( const char * str ) const {
- return strcmp( _buf , str ) != 0;
- }
-
- bool empty() const {
- return _buf == 0 || _buf[0] == 0;
- }
-
- private:
- size_t _size;
- char * _buf;
- };
-
- ostream& operator<<( ostream &s, const ThreadSafeString &o );
-
- /** A generic pointer type for function arguments.
- * It will convert from any pointer type except auto_ptr.
- * Semantics are the same as passing the pointer returned from get()
- * const ptr<T> => T * const
- * ptr<const T> => T const * or const T*
- */
- template <typename T>
- struct ptr {
-
- ptr() : _p(NULL) {}
-
- // convert to ptr<T>
- ptr(T* p) : _p(p) {} // needed for NULL
- template<typename U> ptr(U* p) : _p(p) {}
- template<typename U> ptr(const ptr<U>& p) : _p(p) {}
- template<typename U> ptr(const boost::shared_ptr<U>& p) : _p(p.get()) {}
- template<typename U> ptr(const boost::scoped_ptr<U>& p) : _p(p.get()) {}
- //template<typename U> ptr(const auto_ptr<U>& p) : _p(p.get()) {}
-
- // assign to ptr<T>
- ptr& operator= (T* p) { _p = p; return *this; } // needed for NULL
- template<typename U> ptr& operator= (U* p) { _p = p; return *this; }
- template<typename U> ptr& operator= (const ptr<U>& p) { _p = p; return *this; }
- template<typename U> ptr& operator= (const boost::shared_ptr<U>& p) { _p = p.get(); return *this; }
- template<typename U> ptr& operator= (const boost::scoped_ptr<U>& p) { _p = p.get(); return *this; }
- //template<typename U> ptr& operator= (const auto_ptr<U>& p) { _p = p.get(); return *this; }
-
- // use
- T* operator->() const { return _p; }
- T& operator*() const { return *_p; }
-
- // convert from ptr<T>
- operator T* () const { return _p; }
-
- private:
- T* _p;
- };
-
-
-
- /** Hmmmm */
- using namespace boost;
-
-} // namespace mongo
diff --git a/util/hashtab.h b/util/hashtab.h
deleted file mode 100644
index f1a33068e07..00000000000
--- a/util/hashtab.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/* hashtab.h
-
- Simple, fixed size hash table. Darn simple.
-
- Uses a contiguous block of memory, so you can put it in a memory mapped file very easily.
-*/
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../pch.h"
-#include <map>
-#include "../db/dur.h"
-
-namespace mongo {
-
-#pragma pack(1)
-
- /* you should define:
-
- int Key::hash() return > 0 always.
- */
-
- template <
- class Key,
- class Type
- >
- class HashTable : boost::noncopyable {
- public:
- const char *name;
- struct Node {
- int hash;
- Key k;
- Type value;
- bool inUse() {
- return hash != 0;
- }
- void setUnused() {
- hash = 0;
- }
- };
- void* _buf;
- int n; // number of hashtable buckets
- int maxChain;
-
- Node& nodes(int i) {
- Node *nodes = (Node *) _buf;
- return nodes[i];
- }
-
- int _find(const Key& k, bool& found) {
- found = false;
- int h = k.hash();
- int i = h % n;
- int start = i;
- int chain = 0;
- int firstNonUsed = -1;
- while ( 1 ) {
- if ( !nodes(i).inUse() ) {
- if ( firstNonUsed < 0 )
- firstNonUsed = i;
- }
-
- if ( nodes(i).hash == h && nodes(i).k == k ) {
- if ( chain >= 200 )
- out() << "warning: hashtable " << name << " long chain " << endl;
- found = true;
- return i;
- }
- chain++;
- i = (i+1) % n;
- if ( i == start ) {
- // shouldn't get here / defensive for infinite loops
- out() << "error: hashtable " << name << " is full n:" << n << endl;
- return -1;
- }
- if( chain >= maxChain ) {
- if ( firstNonUsed >= 0 )
- return firstNonUsed;
- out() << "error: hashtable " << name << " max chain reached:" << maxChain << endl;
- return -1;
- }
- }
- }
-
- public:
- /* buf must be all zeroes on initialization. */
- HashTable(void* buf, int buflen, const char *_name) : name(_name) {
- int m = sizeof(Node);
- // out() << "hashtab init, buflen:" << buflen << " m:" << m << endl;
- n = buflen / m;
- if ( (n & 1) == 0 )
- n--;
- maxChain = (int) (n * 0.05);
- _buf = buf;
- //nodes = (Node *) buf;
-
- if ( sizeof(Node) != 628 ) {
- out() << "HashTable() " << _name << " sizeof(node):" << sizeof(Node) << " n:" << n << " sizeof(Key): " << sizeof(Key) << " sizeof(Type):" << sizeof(Type) << endl;
- assert( sizeof(Node) == 628 );
- }
-
- }
-
- Type* get(const Key& k) {
- bool found;
- int i = _find(k, found);
- if ( found )
- return &nodes(i).value;
- return 0;
- }
-
- void kill(const Key& k) {
- bool found;
- int i = _find(k, found);
- if ( i >= 0 && found ) {
- Node* n = &nodes(i);
- n = getDur().writing(n);
- n->k.kill();
- n->setUnused();
- }
- }
-
- /** returns false if too full */
- bool put(const Key& k, const Type& value) {
- bool found;
- int i = _find(k, found);
- if ( i < 0 )
- return false;
- Node* n = getDur().writing( &nodes(i) );
- if ( !found ) {
- n->k = k;
- n->hash = k.hash();
- }
- else {
- assert( n->hash == k.hash() );
- }
- n->value = value;
- return true;
- }
-
- typedef void (*IteratorCallback)( const Key& k , Type& v );
- void iterAll( IteratorCallback callback ) {
- for ( int i=0; i<n; i++ ) {
- if ( nodes(i).inUse() ) {
- callback( nodes(i).k , nodes(i).value );
- }
- }
- }
-
- // TODO: should probably use boost::bind for this, but didn't want to look at it
- typedef void (*IteratorCallback2)( const Key& k , Type& v , void * extra );
- void iterAll( IteratorCallback2 callback , void * extra ) {
- for ( int i=0; i<n; i++ ) {
- if ( nodes(i).inUse() ) {
- callback( nodes(i).k , nodes(i).value , extra );
- }
- }
- }
-
- };
-
-#pragma pack()
-
-} // namespace mongo
diff --git a/util/heapcheck.h b/util/heapcheck.h
deleted file mode 100644
index 95da9538db5..00000000000
--- a/util/heapcheck.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// @file heapcheck.h
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#if defined(HEAP_CHECKING)
-
-#include <google/heap-checker.h>
-
-#define IGNORE_OBJECT( a ) HeapLeakChecker::IgnoreObject( a )
-#define UNIGNORE_OBJECT( a ) HeapLeakChecker::UnIgnoreObject( a )
-
-#else
-
-#define IGNORE_OBJECT( a )
-#define UNIGNORE_OBJECT( a )
-
-#endif
diff --git a/util/hex.h b/util/hex.h
deleted file mode 100644
index 8cf30f2d9d3..00000000000
--- a/util/hex.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// util/hex.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
- //can't use hex namespace because it conflicts with hex iostream function
- inline int fromHex( char c ) {
- if ( '0' <= c && c <= '9' )
- return c - '0';
- if ( 'a' <= c && c <= 'f' )
- return c - 'a' + 10;
- if ( 'A' <= c && c <= 'F' )
- return c - 'A' + 10;
- assert( false );
- return 0xff;
- }
- inline char fromHex( const char *c ) {
- return (char)(( fromHex( c[ 0 ] ) << 4 ) | fromHex( c[ 1 ] ));
- }
-
- inline string toHex(const void* inRaw, int len) {
- static const char hexchars[] = "0123456789ABCDEF";
-
- StringBuilder out;
- const char* in = reinterpret_cast<const char*>(inRaw);
- for (int i=0; i<len; ++i) {
- char c = in[i];
- char hi = hexchars[(c & 0xF0) >> 4];
- char lo = hexchars[(c & 0x0F)];
-
- out << hi << lo;
- }
-
- return out.str();
- }
-
- inline string toHexLower(const void* inRaw, int len) {
- static const char hexchars[] = "0123456789abcdef";
-
- StringBuilder out;
- const char* in = reinterpret_cast<const char*>(inRaw);
- for (int i=0; i<len; ++i) {
- char c = in[i];
- char hi = hexchars[(c & 0xF0) >> 4];
- char lo = hexchars[(c & 0x0F)];
-
- out << hi << lo;
- }
-
- return out.str();
- }
-}
diff --git a/util/histogram.cpp b/util/histogram.cpp
deleted file mode 100644
index 17a85059d58..00000000000
--- a/util/histogram.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-// histogram.cc
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <iomanip>
-#include <limits>
-#include <sstream>
-
-#include "histogram.h"
-
-namespace mongo {
-
- using std::ostringstream;
- using std::setfill;
- using std::setw;
-
- Histogram::Histogram( const Options& opts )
- : _initialValue( opts.initialValue )
- , _numBuckets( opts.numBuckets )
- , _boundaries( new uint32_t[_numBuckets] )
- , _buckets( new uint64_t[_numBuckets] ) {
-
- // TODO more sanity checks
- // + not too few buckets
- // + initialBucket and bucketSize fit within 32 bit ints
-
- // _boundaries store the maximum value falling in that bucket.
- if ( opts.exponential ) {
- uint32_t twoPow = 1; // 2^0
- for ( uint32_t i = 0; i < _numBuckets - 1; i++) {
- _boundaries[i] = _initialValue + opts.bucketSize * twoPow;
- twoPow *= 2; // 2^i+1
- }
- }
- else {
- _boundaries[0] = _initialValue + opts.bucketSize;
- for ( uint32_t i = 1; i < _numBuckets - 1; i++ ) {
- _boundaries[i] = _boundaries[ i-1 ] + opts.bucketSize;
- }
- }
- _boundaries[ _numBuckets-1 ] = std::numeric_limits<uint32_t>::max();
-
- for ( uint32_t i = 0; i < _numBuckets; i++ ) {
- _buckets[i] = 0;
- }
- }
-
- Histogram::~Histogram() {
- delete [] _boundaries;
- delete [] _buckets;
- }
-
- void Histogram::insert( uint32_t element ) {
- if ( element < _initialValue) return;
-
- _buckets[ _findBucket(element) ] += 1;
- }
-
- string Histogram::toHTML() const {
- uint64_t max = 0;
- for ( uint32_t i = 0; i < _numBuckets; i++ ) {
- if ( _buckets[i] > max ) {
- max = _buckets[i];
- }
- }
- if ( max == 0 ) {
- return "histogram is empty\n";
- }
-
- // normalize buckets to max
- const int maxBar = 20;
- ostringstream ss;
- for ( uint32_t i = 0; i < _numBuckets; i++ ) {
- int barSize = _buckets[i] * maxBar / max;
- ss << string( barSize,'*' )
- << setfill(' ') << setw( maxBar-barSize + 12 )
- << _boundaries[i] << '\n';
- }
-
- return ss.str();
- }
-
- uint64_t Histogram::getCount( uint32_t bucket ) const {
- if ( bucket >= _numBuckets ) return 0;
-
- return _buckets[ bucket ];
- }
-
- uint32_t Histogram::getBoundary( uint32_t bucket ) const {
- if ( bucket >= _numBuckets ) return 0;
-
- return _boundaries[ bucket ];
- }
-
- uint32_t Histogram::getBucketsNum() const {
- return _numBuckets;
- }
-
- uint32_t Histogram::_findBucket( uint32_t element ) const {
- // TODO assert not too small a value?
-
- uint32_t low = 0;
- uint32_t high = _numBuckets - 1;
- while ( low < high ) {
- // low + ( (high - low) / 2 );
- uint32_t mid = ( low + high ) >> 1;
- if ( element > _boundaries[ mid ] ) {
- low = mid + 1;
- }
- else {
- high = mid;
- }
- }
- return low;
- }
-
-} // namespace mongo
diff --git a/util/histogram.h b/util/histogram.h
deleted file mode 100644
index 40ec5628dda..00000000000
--- a/util/histogram.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// histogram.h
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef UTIL_HISTOGRAM_HEADER
-#define UTIL_HISTOGRAM_HEADER
-
-#include "../pch.h"
-
-#include <string>
-
-namespace mongo {
-
- using std::string;
-
- /**
- * A histogram for a 32-bit integer range.
- */
- class Histogram {
- public:
- /**
- * Construct a histogram with 'numBuckets' buckets, optionally
- * having the first bucket start at 'initialValue' rather than
- * 0. By default, the histogram buckets will be 'bucketSize' wide.
- *
- * Usage example:
- * Histogram::Options opts;
- * opts.numBuckets = 3;
- * opts.bucketSize = 10;
- * Histogram h( opts );
- *
- * Generates the bucket ranges [0..10],[11..20],[21..max_int]
- *
- * Alternatively, the flag 'exponential' could be turned on, in
- * which case a bucket's maximum value will be
- * initialValue + bucketSize * 2 ^ [0..numBuckets-1]
- *
- * Usage example:
- * Histogram::Options opts;
- * opts.numBuckets = 4;
- * opts.bucketSize = 125;
- * opts.exponential = true;
- * Histogram h( opts );
- *
- * Generates the bucket ranges [0..125],[126..250],[251..500],[501..max_int]
- */
- struct Options {
- boost::uint32_t numBuckets;
- boost::uint32_t bucketSize;
- boost::uint32_t initialValue;
-
- // use exponential buckets?
- bool exponential;
-
- Options()
- : numBuckets(0)
- , bucketSize(0)
- , initialValue(0)
- , exponential(false) {}
- };
- explicit Histogram( const Options& opts );
- ~Histogram();
-
- /**
- * Find the bucket that 'element' falls into and increment its count.
- */
- void insert( boost::uint32_t element );
-
- /**
- * Render the histogram as string that can be used inside an
- * HTML doc.
- */
- string toHTML() const;
-
- // testing interface below -- consider it private
-
- /**
- * Return the count for the 'bucket'-th bucket.
- */
- boost::uint64_t getCount( boost::uint32_t bucket ) const;
-
- /**
- * Return the maximum element that would fall in the
- * 'bucket'-th bucket.
- */
- boost::uint32_t getBoundary( boost::uint32_t bucket ) const;
-
- /**
- * Return the number of buckets in this histogram.
- */
- boost::uint32_t getBucketsNum() const;
-
- private:
- /**
- * Returns the bucket where 'element' should fall
- * into. Currently assumes that 'element' is greater than the
- * minimum 'inialValue'.
- */
- boost::uint32_t _findBucket( boost::uint32_t element ) const;
-
- boost::uint32_t _initialValue; // no value lower than it is recorded
- boost::uint32_t _numBuckets; // total buckets in the histogram
-
- // all below owned here
- boost::uint32_t* _boundaries; // maximum element of each bucket
- boost::uint64_t* _buckets; // current count of each bucket
-
- Histogram( const Histogram& );
- Histogram& operator=( const Histogram& );
- };
-
-} // namespace mongo
-
-#endif // UTIL_HISTOGRAM_HEADER
diff --git a/util/log.cpp b/util/log.cpp
deleted file mode 100644
index 0dc75eddf6e..00000000000
--- a/util/log.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/** @file log.cpp
- */
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "assert_util.h"
-#include "assert.h"
-#include <cmath>
-#include "time_support.h"
-using namespace std;
-
-#ifdef _WIN32
-# include <io.h>
-# include <fcntl.h>
-#else
-# include <cxxabi.h>
-# include <sys/file.h>
-#endif
-
-#ifdef _WIN32
-# define dup2 _dup2 // Microsoft headers use ISO C names
-# define fileno _fileno
-#endif
-
-namespace mongo {
-
- Nullstream nullstream;
- vector<Tee*>* Logstream::globalTees = 0;
-
- thread_specific_ptr<Logstream> Logstream::tsp;
-
- class LoggingManager {
- public:
- LoggingManager()
- : _enabled(0) , _file(0) {
- }
-
- void start( const string& lp , bool append ) {
- uassert( 10268 , "LoggingManager already started" , ! _enabled );
- _append = append;
-
- bool exists = boost::filesystem::exists(lp);
-
- // test path
- FILE * test = fopen( lp.c_str() , _append ? "a" : "w" );
- if ( ! test ) {
- if (boost::filesystem::is_directory(lp)) {
- cout << "logpath [" << lp << "] should be a file name not a directory" << endl;
- }
- else {
- cout << "can't open [" << lp << "] for log file: " << errnoWithDescription() << endl;
- }
- dbexit( EXIT_BADOPTIONS );
- assert( 0 );
- }
-
- if (append && exists){
- // two blank lines before and after
- const string msg = "\n\n***** SERVER RESTARTED *****\n\n\n";
- massert(14036, errnoWithPrefix("couldn't write to log file"),
- fwrite(msg.data(), 1, msg.size(), test) == msg.size());
- }
-
- fclose( test );
-
- _path = lp;
- _enabled = 1;
- rotate();
- }
-
- void rotate() {
- if ( ! _enabled ) {
- cout << "LoggingManager not enabled" << endl;
- return;
- }
-
- if ( _file ) {
-
-#ifdef POSIX_FADV_DONTNEED
- posix_fadvise(fileno(_file), 0, 0, POSIX_FADV_DONTNEED);
-#endif
-
- // Rename the (open) existing log file to a timestamped name
- stringstream ss;
- ss << _path << "." << terseCurrentTime( false );
- string s = ss.str();
- rename( _path.c_str() , s.c_str() );
- }
-
- FILE* tmp = 0; // The new file using the original logpath name
-
-#if _WIN32
- // We rename an open log file (above, on next rotation) and the trick to getting Windows to do that is
- // to open the file with FILE_SHARE_DELETE. So, we can't use the freopen() call that non-Windows
- // versions use because it would open the file without the FILE_SHARE_DELETE flag we need.
- //
- HANDLE newFileHandle = CreateFileA(
- _path.c_str(),
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- if ( INVALID_HANDLE_VALUE != newFileHandle ) {
- int newFileDescriptor = _open_osfhandle( reinterpret_cast<intptr_t>(newFileHandle), _O_APPEND );
- tmp = _fdopen( newFileDescriptor, _append ? "a" : "w" );
- }
-#else
- tmp = freopen(_path.c_str(), _append ? "a" : "w", stdout);
-#endif
- if ( !tmp ) {
- cerr << "can't open: " << _path.c_str() << " for log file" << endl;
- dbexit( EXIT_BADOPTIONS );
- assert( 0 );
- }
-
- // redirect stdout and stderr to log file
- dup2( fileno( tmp ), 1 ); // stdout
- dup2( fileno( tmp ), 2 ); // stderr
-
- Logstream::setLogFile(tmp); // after this point no thread will be using old file
-
-#if _WIN32
- if ( _file )
- fclose( _file ); // In Windows, we still have the old file open, close it now
-#endif
-
-#if 0 // enable to test redirection
- cout << "written to cout" << endl;
- cerr << "written to cerr" << endl;
- log() << "written to log()" << endl;
-#endif
-
- _file = tmp; // Save new file for next rotation
- }
-
- private:
- bool _enabled;
- string _path;
- bool _append;
- FILE * _file;
-
- } loggingManager;
-
- void initLogging( const string& lp , bool append ) {
- cout << "all output going to: " << lp << endl;
- loggingManager.start( lp , append );
- }
-
- void rotateLogs( int signal ) {
- loggingManager.rotate();
- }
-
- // done *before* static initialization
- FILE* Logstream::logfile = stdout;
-
-}
diff --git a/util/log.h b/util/log.h
deleted file mode 100644
index 660bfbee30e..00000000000
--- a/util/log.h
+++ /dev/null
@@ -1,531 +0,0 @@
-// @file log.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string.h>
-#include <errno.h>
-#include "../bson/util/builder.h"
-
-#ifndef _WIN32
-//#include <syslog.h>
-#endif
-
-namespace mongo {
-
- enum LogLevel { LL_DEBUG , LL_INFO , LL_NOTICE , LL_WARNING , LL_ERROR , LL_SEVERE };
-
- inline const char * logLevelToString( LogLevel l ) {
- switch ( l ) {
- case LL_DEBUG:
- case LL_INFO:
- case LL_NOTICE:
- return "";
- case LL_WARNING:
- return "warning" ;
- case LL_ERROR:
- return "ERROR";
- case LL_SEVERE:
- return "SEVERE";
- default:
- return "UNKNOWN";
- }
- }
-
- class LabeledLevel {
- public:
-
- LabeledLevel( int level ) : _level( level ) {}
- LabeledLevel( const char* label, int level ) : _label( label ), _level( level ) {}
- LabeledLevel( const string& label, int level ) : _label( label ), _level( level ) {}
-
- LabeledLevel operator+( int i ) const {
- return LabeledLevel( _label, _level + i );
- }
-
- LabeledLevel operator+( const char* label ) const {
- if( _label == "" )
- return LabeledLevel( label, _level );
- return LabeledLevel( _label + string("::") + label, _level );
- }
-
- LabeledLevel operator+( string& label ) const {
- return LabeledLevel( _label + string("::") + label, _level );
- }
-
- LabeledLevel operator-( int i ) const {
- return LabeledLevel( _label, _level - i );
- }
-
- const string& getLabel() const { return _label; }
- int getLevel() const { return _level; }
-
- private:
- string _label;
- int _level;
- };
-
- class LazyString {
- public:
- virtual ~LazyString() {}
- virtual string val() const = 0;
- };
-
- // Utility class for stringifying object only when val() called.
- template< class T >
- class LazyStringImpl : public LazyString {
- public:
- LazyStringImpl( const T &t ) : t_( t ) {}
- virtual string val() const { return t_.toString(); }
- private:
- const T& t_;
- };
-
- class Tee {
- public:
- virtual ~Tee() {}
- virtual void write(LogLevel level , const string& str) = 0;
- };
-
- class Nullstream {
- public:
- virtual Nullstream& operator<< (Tee* tee) {
- return *this;
- }
- virtual ~Nullstream() {}
- virtual Nullstream& operator<<(const char *) {
- return *this;
- }
- virtual Nullstream& operator<<(const string& ) {
- return *this;
- }
- virtual Nullstream& operator<<(const StringData& ) {
- return *this;
- }
- virtual Nullstream& operator<<(char *) {
- return *this;
- }
- virtual Nullstream& operator<<(char) {
- return *this;
- }
- virtual Nullstream& operator<<(int) {
- return *this;
- }
- virtual Nullstream& operator<<(ExitCode) {
- return *this;
- }
- virtual Nullstream& operator<<(unsigned long) {
- return *this;
- }
- virtual Nullstream& operator<<(long) {
- return *this;
- }
- virtual Nullstream& operator<<(unsigned) {
- return *this;
- }
- virtual Nullstream& operator<<(unsigned short) {
- return *this;
- }
- virtual Nullstream& operator<<(double) {
- return *this;
- }
- virtual Nullstream& operator<<(void *) {
- return *this;
- }
- virtual Nullstream& operator<<(const void *) {
- return *this;
- }
- virtual Nullstream& operator<<(long long) {
- return *this;
- }
- virtual Nullstream& operator<<(unsigned long long) {
- return *this;
- }
- virtual Nullstream& operator<<(bool) {
- return *this;
- }
- virtual Nullstream& operator<<(const LazyString&) {
- return *this;
- }
- template< class T >
- Nullstream& operator<<(T *t) {
- return operator<<( static_cast<void*>( t ) );
- }
- template< class T >
- Nullstream& operator<<(const T *t) {
- return operator<<( static_cast<const void*>( t ) );
- }
- template< class T >
- Nullstream& operator<<(const shared_ptr<T> p ) {
- T * t = p.get();
- if ( ! t )
- *this << "null";
- else
- *this << *t;
- return *this;
- }
- template< class T >
- Nullstream& operator<<(const T &t) {
- return operator<<( static_cast<const LazyString&>( LazyStringImpl< T >( t ) ) );
- }
-
- virtual Nullstream& operator<< (ostream& ( *endl )(ostream&)) {
- return *this;
- }
- virtual Nullstream& operator<< (ios_base& (*hex)(ios_base&)) {
- return *this;
- }
-
- virtual void flush(Tee *t = 0) {}
- };
- extern Nullstream nullstream;
-
- class Logstream : public Nullstream {
- static mongo::mutex mutex;
- static int doneSetup;
- stringstream ss;
- int indent;
- LogLevel logLevel;
- static FILE* logfile;
- static boost::scoped_ptr<ostream> stream;
- static vector<Tee*> * globalTees;
- public:
- inline static void logLockless( const StringData& s );
-
- static void setLogFile(FILE* f) {
- scoped_lock lk(mutex);
- logfile = f;
- }
-
- static int magicNumber() {
- return 1717;
- }
-
- static int getLogDesc() {
- int fd = -1;
- if (logfile != NULL)
-#if defined(_WIN32)
- // the ISO C++ conformant name is _fileno
- fd = _fileno( logfile );
-#else
- fd = fileno( logfile );
-#endif
- return fd;
- }
-
- inline void flush(Tee *t = 0);
-
- inline Nullstream& setLogLevel(LogLevel l) {
- logLevel = l;
- return *this;
- }
-
- /** note these are virtual */
- Logstream& operator<<(const char *x) { ss << x; return *this; }
- Logstream& operator<<(const string& x) { ss << x; return *this; }
- Logstream& operator<<(const StringData& x) { ss << x.data(); return *this; }
- Logstream& operator<<(char *x) { ss << x; return *this; }
- Logstream& operator<<(char x) { ss << x; return *this; }
- Logstream& operator<<(int x) { ss << x; return *this; }
- Logstream& operator<<(ExitCode x) { ss << x; return *this; }
- Logstream& operator<<(long x) { ss << x; return *this; }
- Logstream& operator<<(unsigned long x) { ss << x; return *this; }
- Logstream& operator<<(unsigned x) { ss << x; return *this; }
- Logstream& operator<<(unsigned short x){ ss << x; return *this; }
- Logstream& operator<<(double x) { ss << x; return *this; }
- Logstream& operator<<(void *x) { ss << x; return *this; }
- Logstream& operator<<(const void *x) { ss << x; return *this; }
- Logstream& operator<<(long long x) { ss << x; return *this; }
- Logstream& operator<<(unsigned long long x) { ss << x; return *this; }
- Logstream& operator<<(bool x) { ss << x; return *this; }
-
- Logstream& operator<<(const LazyString& x) {
- ss << x.val();
- return *this;
- }
- Nullstream& operator<< (Tee* tee) {
- ss << '\n';
- flush(tee);
- return *this;
- }
- Logstream& operator<< (ostream& ( *_endl )(ostream&)) {
- ss << '\n';
- flush(0);
- return *this;
- }
- Logstream& operator<< (ios_base& (*_hex)(ios_base&)) {
- ss << _hex;
- return *this;
- }
-
- Logstream& prolog() {
- return *this;
- }
-
- void addGlobalTee( Tee * t ) {
- if ( ! globalTees )
- globalTees = new vector<Tee*>();
- globalTees->push_back( t );
- }
-
- void indentInc(){ indent++; }
- void indentDec(){ indent--; }
- int getIndent() const { return indent; }
-
- private:
- static thread_specific_ptr<Logstream> tsp;
- Logstream() {
- indent = 0;
- _init();
- }
- void _init() {
- ss.str("");
- logLevel = LL_INFO;
- }
- public:
- static Logstream& get() {
- if ( StaticObserver::_destroyingStatics ) {
- cout << "Logstream::get called in uninitialized state" << endl;
- }
- Logstream *p = tsp.get();
- if( p == 0 )
- tsp.reset( p = new Logstream() );
- return *p;
- }
- };
-
- extern int logLevel;
- extern int tlogLevel;
-
- inline Nullstream& out( int level = 0 ) {
- if ( level > logLevel )
- return nullstream;
- return Logstream::get();
- }
-
- /* flush the log stream if the log level is
- at the specified level or higher. */
- inline void logflush(int level = 0) {
- if( level > logLevel )
- Logstream::get().flush(0);
- }
-
- /* without prolog */
- inline Nullstream& _log( int level = 0 ) {
- if ( level > logLevel )
- return nullstream;
- return Logstream::get();
- }
-
- /** logging which we may not want during unit tests (dbtests) runs.
- set tlogLevel to -1 to suppress tlog() output in a test program. */
- inline Nullstream& tlog( int level = 0 ) {
- if ( level > tlogLevel || level > logLevel )
- return nullstream;
- return Logstream::get().prolog();
- }
-
- inline Nullstream& log( int level ) {
- if ( level > logLevel )
- return nullstream;
- return Logstream::get().prolog();
- }
-
-#define MONGO_LOG(level) if ( MONGO_unlikely(logLevel >= (level)) ) log( level )
-#define LOG MONGO_LOG
-
- inline Nullstream& log( LogLevel l ) {
- return Logstream::get().prolog().setLogLevel( l );
- }
-
- inline Nullstream& log( const LabeledLevel& ll ) {
- Nullstream& stream = log( ll.getLevel() );
- if( ll.getLabel() != "" )
- stream << "[" << ll.getLabel() << "] ";
- return stream;
- }
-
- inline Nullstream& log() {
- return Logstream::get().prolog();
- }
-
- inline Nullstream& error() {
- return log( LL_ERROR );
- }
-
- inline Nullstream& warning() {
- return log( LL_WARNING );
- }
-
- /* default impl returns "" -- mongod overrides */
- extern const char * (*getcurns)();
-
- inline Nullstream& problem( int level = 0 ) {
- if ( level > logLevel )
- return nullstream;
- Logstream& l = Logstream::get().prolog();
- l << ' ' << getcurns() << ' ';
- return l;
- }
-
- /**
- log to a file rather than stdout
- defined in assert_util.cpp
- */
- void initLogging( const string& logpath , bool append );
- void rotateLogs( int signal = 0 );
-
- std::string toUtf8String(const std::wstring& wide);
-
- inline string errnoWithDescription(int x = errno) {
- stringstream s;
- s << "errno:" << x << ' ';
-
-#if defined(_WIN32)
- LPTSTR errorText = NULL;
- FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM
- |FORMAT_MESSAGE_ALLOCATE_BUFFER
- |FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- x, 0,
- (LPTSTR) &errorText, // output
- 0, // minimum size for output buffer
- NULL);
- if( errorText ) {
- string x = toUtf8String(errorText);
- for( string::iterator i = x.begin(); i != x.end(); i++ ) {
- if( *i == '\n' || *i == '\r' )
- break;
- s << *i;
- }
- LocalFree(errorText);
- }
- else
- s << strerror(x);
- /*
- DWORD n = FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, x,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf, 0, NULL);
- */
-#else
- s << strerror(x);
-#endif
- return s.str();
- }
-
- /** output the error # and error message with prefix.
- handy for use as parm in uassert/massert.
- */
- string errnoWithPrefix( const char * prefix );
-
- void Logstream::logLockless( const StringData& s ) {
- if ( s.size() == 0 )
- return;
-
- if ( doneSetup == 1717 ) {
- if (fwrite(s.data(), s.size(), 1, logfile)) {
- fflush(logfile);
- }
- else {
- int x = errno;
- cout << "Failed to write to logfile: " << errnoWithDescription(x) << endl;
- }
- }
- else {
- cout << s.data();
- cout.flush();
- }
- }
-
- void Logstream::flush(Tee *t) {
- // this ensures things are sane
- if ( doneSetup == 1717 ) {
- string msg = ss.str();
- string threadName = getThreadName();
- const char * type = logLevelToString(logLevel);
-
- int spaceNeeded = (int)(msg.size() + 64 + threadName.size());
- int bufSize = 128;
- while ( bufSize < spaceNeeded )
- bufSize += 128;
-
- BufBuilder b(bufSize);
- time_t_to_String( time(0) , b.grow(20) );
- if (!threadName.empty()) {
- b.appendChar( '[' );
- b.appendStr( threadName , false );
- b.appendChar( ']' );
- b.appendChar( ' ' );
- }
-
- for ( int i=0; i<indent; i++ )
- b.appendChar( '\t' );
-
- if ( type[0] ) {
- b.appendStr( type , false );
- b.appendStr( ": " , false );
- }
-
- b.appendStr( msg );
-
- string out( b.buf() , b.len() - 1);
-
- scoped_lock lk(mutex);
-
- if( t ) t->write(logLevel,out);
- if ( globalTees ) {
- for ( unsigned i=0; i<globalTees->size(); i++ )
- (*globalTees)[i]->write(logLevel,out);
- }
-
-#ifndef _WIN32
- //syslog( LOG_INFO , "%s" , cc );
-#endif
- if(fwrite(out.data(), out.size(), 1, logfile)) {
- fflush(logfile);
- }
- else {
- int x = errno;
- cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl;
- }
-
-#ifdef POSIX_FADV_DONTNEED
- // This only applies to pages that have already been flushed
- RARELY posix_fadvise(fileno(logfile), 0, 0, POSIX_FADV_DONTNEED);
-#endif
-
- }
- _init();
- }
-
- struct LogIndentLevel {
- LogIndentLevel(){
- Logstream::get().indentInc();
- }
- ~LogIndentLevel(){
- Logstream::get().indentDec();
- }
- };
-
- extern Tee* const warnings; // Things put here go in serverStatus
-
-} // namespace mongo
diff --git a/util/logfile.cpp b/util/logfile.cpp
deleted file mode 100644
index 65c56e220a4..00000000000
--- a/util/logfile.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-// @file logfile.cpp simple file log writing / journaling
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-#include "logfile.h"
-#include "text.h"
-#include "mongoutils/str.h"
-#include "unittest.h"
-
-using namespace mongoutils;
-
-namespace mongo {
- struct LogfileTest : public UnitTest {
- LogfileTest() { }
- void run() {
- if( 0 && debug ) {
- try {
- LogFile f("logfile_test");
- void *p = malloc(16384);
- char *buf = (char*) p;
- buf += 4095;
- buf = (char*) (((size_t)buf)&(~0xfff));
- memset(buf, 'z', 8192);
- buf[8190] = '\n';
- buf[8191] = 'B';
- buf[0] = 'A';
- f.synchronousAppend(buf, 8192);
- f.synchronousAppend(buf, 8192);
- free(p);
- }
- catch(DBException& e ) {
- log() << "logfile.cpp test failed : " << e.what() << endl;
- throw;
- }
- }
- }
- } __test;
-}
-
-#if defined(_WIN32)
-
-namespace mongo {
-
- LogFile::LogFile(string name) : _name(name) {
- _fd = CreateFile(
- toNativeString(name.c_str()).c_str(),
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
- NULL);
- if( _fd == INVALID_HANDLE_VALUE ) {
- DWORD e = GetLastError();
- uasserted(13518, str::stream() << "couldn't open file " << name << " for writing " << errnoWithDescription(e));
- }
- SetFilePointer(_fd, 0, 0, FILE_BEGIN);
- }
-
- LogFile::~LogFile() {
- if( _fd != INVALID_HANDLE_VALUE )
- CloseHandle(_fd);
- }
-
- void LogFile::truncate() {
- verify(15870, _fd != INVALID_HANDLE_VALUE);
-
- if (!SetEndOfFile(_fd)){
- msgasserted(15871, "Couldn't truncate file: " + errnoWithDescription());
- }
- }
-
- void LogFile::synchronousAppend(const void *_buf, size_t _len) {
- const size_t BlockSize = 8 * 1024 * 1024;
- assert(_fd);
- assert(_len % 4096 == 0);
- const char *buf = (const char *) _buf;
- size_t left = _len;
- while( left ) {
- size_t toWrite = min(left, BlockSize);
- DWORD written;
- if( !WriteFile(_fd, buf, toWrite, &written, NULL) ) {
- DWORD e = GetLastError();
- if( e == 87 )
- msgasserted(13519, "error 87 appending to file - invalid parameter");
- else
- uasserted(13517, str::stream() << "error appending to file " << _name << ' ' << _len << ' ' << toWrite << ' ' << errnoWithDescription(e));
- }
- else {
- dassert( written == toWrite );
- }
- left -= written;
- buf += written;
- }
- }
-
-}
-
-#else
-
-// posix
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include "paths.h"
-
-namespace mongo {
-
- LogFile::LogFile(string name) : _name(name) {
- int options = O_CREAT
- | O_WRONLY
-#if defined(O_DIRECT)
- | O_DIRECT
-#endif
-#if defined(O_NOATIME)
- | O_NOATIME
-#endif
- ;
-
- _fd = open(name.c_str(), options, S_IRUSR | S_IWUSR);
-
-#if defined(O_DIRECT)
- _direct = true;
- if( _fd < 0 ) {
- _direct = false;
- options &= ~O_DIRECT;
- _fd = open(name.c_str(), options, S_IRUSR | S_IWUSR);
- }
-#else
- _direct = false;
-#endif
-
- if( _fd < 0 ) {
- uasserted(13516, str::stream() << "couldn't open file " << name << " for writing " << errnoWithDescription());
- }
-
- flushMyDirectory(name);
- }
-
- LogFile::~LogFile() {
- if( _fd >= 0 )
- close(_fd);
- _fd = -1;
- }
-
- void LogFile::truncate() {
- verify(15872, _fd >= 0);
-
- BOOST_STATIC_ASSERT(sizeof(off_t) == 8); // we don't want overflow here
- const off_t pos = lseek(_fd, 0, SEEK_CUR); // doesn't actually seek
- if (ftruncate(_fd, pos) != 0){
- msgasserted(15873, "Couldn't truncate file: " + errnoWithDescription());
- }
- }
-
- void LogFile::synchronousAppend(const void *b, size_t len) {
-
- const char *buf = static_cast<const char *>( b );
- ssize_t charsToWrite = static_cast<ssize_t>( len );
-
- if (charsToWrite < 0 || _fd < 0) {
- log() << "LogFile::synchronousAppend preconditions not met.";
- ::abort();
- }
-
-#ifdef POSIX_FADV_DONTNEED
- const off_t pos = lseek(_fd, 0, SEEK_CUR); // doesn't actually seek
-#endif
-
- while ( charsToWrite > 0 ) {
- const ssize_t written = write( _fd, buf, static_cast<size_t>( charsToWrite ) );
- if ( -1 == written ) {
- log() << "LogFile::synchronousAppend failed with " << charsToWrite
- << " bytes unwritten out of " << len << " bytes; b=" << b << ' '
- << errnoWithDescription() << std::endl;
- ::abort();
- }
- buf += written;
- charsToWrite -= written;
- }
-
- if(
-#if defined(__linux__)
- fdatasync(_fd) < 0
-#else
- fsync(_fd)
-#endif
- ) {
- log() << "error appending to file on fsync " << ' ' << errnoWithDescription();
- ::abort();
- }
-
-#ifdef POSIX_FADV_DONTNEED
- if (!_direct)
- posix_fadvise(_fd, pos, len, POSIX_FADV_DONTNEED);
-#endif
- }
-
-}
-
-#endif
diff --git a/util/logfile.h b/util/logfile.h
deleted file mode 100644
index f6d1c94bf22..00000000000
--- a/util/logfile.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// @file logfile.h simple file log writing / journaling
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-namespace mongo {
-
- class LogFile {
- public:
- /** create the file and open. must not already exist.
- throws UserAssertion on i/o error
- */
- LogFile(string name);
-
- /** closes */
- ~LogFile();
-
- /** append to file. does not return until sync'd. uses direct i/o when possible.
- throws UserAssertion on an i/o error
- note direct i/o may have alignment requirements
- */
- void synchronousAppend(const void *buf, size_t len);
-
- const string _name;
-
- void truncate(); // Removes extra data after current position
-
- private:
-#if defined(_WIN32)
- typedef HANDLE fd_type;
-#else
- typedef int fd_type;
-#endif
- fd_type _fd;
- bool _direct; // are we using direct I/O
- };
-
-}
diff --git a/util/lruishmap.h b/util/lruishmap.h
deleted file mode 100644
index ba91bf6f0f6..00000000000
--- a/util/lruishmap.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// lru-ish map.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../pch.h"
-#include "../util/goodies.h"
-
-namespace mongo {
-
- /* Your K object must define:
- int hash() - must always return > 0.
- operator==
- */
-
- template <class K, class V, int MaxChain>
- class LRUishMap {
- public:
- LRUishMap(int _n) {
- n = nextPrime(_n);
- keys = new K[n];
- hashes = new int[n];
- for ( int i = 0; i < n; i++ ) hashes[i] = 0;
- }
- ~LRUishMap() {
- delete[] keys;
- delete[] hashes;
- }
-
- int _find(const K& k, bool& found) {
- int h = k.hash();
- assert( h > 0 );
- int j = h % n;
- int first = j;
- for ( int i = 0; i < MaxChain; i++ ) {
- if ( hashes[j] == h ) {
- if ( keys[j] == k ) {
- found = true;
- return j;
- }
- }
- else if ( hashes[j] == 0 ) {
- found = false;
- return j;
- }
- }
- found = false;
- return first;
- }
-
- V* find(const K& k) {
- bool found;
- int j = _find(k, found);
- return found ? &values[j] : 0;
- }
-
- private:
- int n;
- K *keys;
- int *hashes;
- V *values;
- };
-
-} // namespace mongo
diff --git a/util/md5.c b/util/md5.c
deleted file mode 100644
index c35d96c5ef5..00000000000
--- a/util/md5.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.c is L. Peter Deutsch
- <ghost@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
- either statically or dynamically; added missing #include <string.h>
- in library.
- 2002-03-11 lpd Corrected argument list for main(), and added int return
- type, in test program and T value program.
- 2002-02-21 lpd Added missing #include <stdio.h> in test program.
- 2000-07-03 lpd Patched to eliminate warnings about "constant is
- unsigned in ANSI C, signed in traditional"; made test program
- self-checking.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
- 1999-05-03 lpd Original version.
- */
-
-#include "md5.h"
-#include <string.h>
-
-#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
-#ifdef ARCH_IS_BIG_ENDIAN
-# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
-#else
-# define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3 0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6 0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9 0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13 0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16 0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19 0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22 0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25 0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28 0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31 0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35 0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38 0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41 0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44 0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47 0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50 0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53 0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57 0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60 0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63 0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
- md5_word_t
- a = pms->abcd[0], b = pms->abcd[1],
- c = pms->abcd[2], d = pms->abcd[3];
- md5_word_t t;
-#if BYTE_ORDER > 0
- /* Define storage only for big-endian CPUs. */
- md5_word_t X[16];
-#else
- /* Define storage for little-endian or both types of CPUs. */
- md5_word_t xbuf[16];
- const md5_word_t *X;
-#endif
-
- {
-#if BYTE_ORDER == 0
- /*
- * Determine dynamically whether this is a big-endian or
- * little-endian machine, since we can use a more efficient
- * algorithm on the latter.
- */
- static const int w = 1;
-
- if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0 /* little-endian */
- {
- /*
- * On little-endian machines, we can process properly aligned
- * data without copying it.
- */
- if (!((data - (const md5_byte_t *)0) & 3)) {
- /* data are properly aligned */
- X = (const md5_word_t *)data;
- } else {
- /* not aligned */
- memcpy(xbuf, data, 64);
- X = xbuf;
- }
- }
-#endif
-#if BYTE_ORDER == 0
- else /* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0 /* big-endian */
- {
- /*
- * On big-endian machines, we must arrange the bytes in the
- * right order.
- */
- const md5_byte_t *xp = data;
- int i;
-
-# if BYTE_ORDER == 0
- X = xbuf; /* (dynamic only) */
-# else
-# define xbuf X /* (static only) */
-# endif
- for (i = 0; i < 16; ++i, xp += 4)
- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
- }
-#endif
- }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
- /* Round 1. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 7, T1);
- SET(d, a, b, c, 1, 12, T2);
- SET(c, d, a, b, 2, 17, T3);
- SET(b, c, d, a, 3, 22, T4);
- SET(a, b, c, d, 4, 7, T5);
- SET(d, a, b, c, 5, 12, T6);
- SET(c, d, a, b, 6, 17, T7);
- SET(b, c, d, a, 7, 22, T8);
- SET(a, b, c, d, 8, 7, T9);
- SET(d, a, b, c, 9, 12, T10);
- SET(c, d, a, b, 10, 17, T11);
- SET(b, c, d, a, 11, 22, T12);
- SET(a, b, c, d, 12, 7, T13);
- SET(d, a, b, c, 13, 12, T14);
- SET(c, d, a, b, 14, 17, T15);
- SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
- /* Round 2. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 1, 5, T17);
- SET(d, a, b, c, 6, 9, T18);
- SET(c, d, a, b, 11, 14, T19);
- SET(b, c, d, a, 0, 20, T20);
- SET(a, b, c, d, 5, 5, T21);
- SET(d, a, b, c, 10, 9, T22);
- SET(c, d, a, b, 15, 14, T23);
- SET(b, c, d, a, 4, 20, T24);
- SET(a, b, c, d, 9, 5, T25);
- SET(d, a, b, c, 14, 9, T26);
- SET(c, d, a, b, 3, 14, T27);
- SET(b, c, d, a, 8, 20, T28);
- SET(a, b, c, d, 13, 5, T29);
- SET(d, a, b, c, 2, 9, T30);
- SET(c, d, a, b, 7, 14, T31);
- SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
- /* Round 3. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + H(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 5, 4, T33);
- SET(d, a, b, c, 8, 11, T34);
- SET(c, d, a, b, 11, 16, T35);
- SET(b, c, d, a, 14, 23, T36);
- SET(a, b, c, d, 1, 4, T37);
- SET(d, a, b, c, 4, 11, T38);
- SET(c, d, a, b, 7, 16, T39);
- SET(b, c, d, a, 10, 23, T40);
- SET(a, b, c, d, 13, 4, T41);
- SET(d, a, b, c, 0, 11, T42);
- SET(c, d, a, b, 3, 16, T43);
- SET(b, c, d, a, 6, 23, T44);
- SET(a, b, c, d, 9, 4, T45);
- SET(d, a, b, c, 12, 11, T46);
- SET(c, d, a, b, 15, 16, T47);
- SET(b, c, d, a, 2, 23, T48);
-#undef SET
-
- /* Round 4. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 6, T49);
- SET(d, a, b, c, 7, 10, T50);
- SET(c, d, a, b, 14, 15, T51);
- SET(b, c, d, a, 5, 21, T52);
- SET(a, b, c, d, 12, 6, T53);
- SET(d, a, b, c, 3, 10, T54);
- SET(c, d, a, b, 10, 15, T55);
- SET(b, c, d, a, 1, 21, T56);
- SET(a, b, c, d, 8, 6, T57);
- SET(d, a, b, c, 15, 10, T58);
- SET(c, d, a, b, 6, 15, T59);
- SET(b, c, d, a, 13, 21, T60);
- SET(a, b, c, d, 4, 6, T61);
- SET(d, a, b, c, 11, 10, T62);
- SET(c, d, a, b, 2, 15, T63);
- SET(b, c, d, a, 9, 21, T64);
-#undef SET
-
- /* Then perform the following additions. (That is increment each
- of the four registers by the value it had before this block
- was started.) */
- pms->abcd[0] += a;
- pms->abcd[1] += b;
- pms->abcd[2] += c;
- pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
- pms->count[0] = pms->count[1] = 0;
- pms->abcd[0] = 0x67452301;
- pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
- pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
- pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
- const md5_byte_t *p = data;
- int left = nbytes;
- int offset = (pms->count[0] >> 3) & 63;
- md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
- if (nbytes <= 0)
- return;
-
- /* Update the message length. */
- pms->count[1] += nbytes >> 29;
- pms->count[0] += nbits;
- if (pms->count[0] < nbits)
- pms->count[1]++;
-
- /* Process an initial partial block. */
- if (offset) {
- int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
- memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
- return;
- p += copy;
- left -= copy;
- md5_process(pms, pms->buf);
- }
-
- /* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
- md5_process(pms, p);
-
- /* Process a final partial block. */
- if (left)
- memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
- static const md5_byte_t pad[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- md5_byte_t data[8];
- int i;
-
- /* Save the length before padding. */
- for (i = 0; i < 8; ++i)
- data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
- /* Pad to 56 bytes mod 64. */
- md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
- /* Append the length. */
- md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
- digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
diff --git a/util/md5.h b/util/md5.h
deleted file mode 100644
index a3f3b6db0e2..00000000000
--- a/util/md5.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.h is L. Peter Deutsch
- <ghost@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Removed support for non-ANSI compilers; removed
- references to Ghostscript; clarified derivation from RFC 1321;
- now handles byte order either statically or dynamically.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
- added conditionalization for C++ compilation from Martin
- Purschke <purschke@bnl.gov>.
- 1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-# define md5_INCLUDED
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
- md5_word_t count[2]; /* message length in bits, lsw first */
- md5_word_t abcd[4]; /* digest buffer */
- md5_byte_t buf[64]; /* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /* Initialize the algorithm. */
- void md5_init(md5_state_t *pms);
-
- /* Append a string to the message. */
- void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
- /* Finish the message and return the digest. */
- void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
diff --git a/util/md5.hpp b/util/md5.hpp
deleted file mode 100644
index dc061719747..00000000000
--- a/util/md5.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// md5.hpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "md5.h"
-
-namespace mongo {
-
- typedef unsigned char md5digest[16];
-
- inline void md5(const void *buf, int nbytes, md5digest digest) {
- md5_state_t st;
- md5_init(&st);
- md5_append(&st, (const md5_byte_t *) buf, nbytes);
- md5_finish(&st, digest);
- }
-
- inline void md5(const char *str, md5digest digest) {
- md5(str, strlen(str), digest);
- }
-
- inline std::string digestToString( md5digest digest ){
- static const char * letters = "0123456789abcdef";
- stringstream ss;
- for ( int i=0; i<16; i++){
- unsigned char c = digest[i];
- ss << letters[ ( c >> 4 ) & 0xf ] << letters[ c & 0xf ];
- }
- return ss.str();
- }
-
- inline std::string md5simpledigest( const void* buf, int nbytes){
- md5digest d;
- md5( buf, nbytes , d );
- return digestToString( d );
- }
-
- inline std::string md5simpledigest( string s ){
- return md5simpledigest(s.data(), s.size());
- }
-
-
-} // namespace mongo
diff --git a/util/md5main.cpp b/util/md5main.cpp
deleted file mode 100644
index 9995fee8fa7..00000000000
--- a/util/md5main.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- Copyright (C) 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5main.c,v 1.1 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.c is L. Peter Deutsch
- <ghost@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Splits off main program into a separate file, md5main.c.
- */
-
-#include "pch.h"
-#include "md5.h"
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-
-/*
- * This file builds an executable that performs various functions related
- * to the MD5 library. Typical compilation:
- * gcc -o md5main -lm md5main.c md5.c
- */
-static const char *const usage = "\
-Usage:\n\
- md5main --test # run the self-test (A.5 of RFC 1321)\n\
- md5main --t-values # print the T values for the library\n\
- md5main --version # print the version of the package\n\
-";
-static const char *const version = "2002-04-13";
-
-/* modified: not static, renamed */
-/* Run the self-test. */
-/*static*/ int
-//do_test(void)
-do_md5_test(void) {
- static const char *const test[7*2] = {
- "", "d41d8cd98f00b204e9800998ecf8427e",
- "a", "0cc175b9c0f1b6a831c399e269772661",
- "abc", "900150983cd24fb0d6963f7d28e17f72",
- "message digest", "f96b697d7cb7938d525a2f31aaf161d0",
- "abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
- "d174ab98d277d9f5a5611c2c9f419d9f",
- "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a"
- };
- int i;
- int status = 0;
-
- for (i = 0; i < 7*2; i += 2) {
- md5_state_t state;
- md5_byte_t digest[16];
- char hex_output[16*2 + 1];
- int di;
-
- md5_init(&state);
- md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
- md5_finish(&state, digest);
- for (di = 0; di < 16; ++di)
- sprintf(hex_output + di * 2, "%02x", digest[di]);
- if (strcmp(hex_output, test[i + 1])) {
- printf("MD5 (\"%s\") = ", test[i]);
- puts(hex_output);
- printf("**** ERROR, should be: %s\n", test[i + 1]);
- status = 1;
- }
- }
-// if (status == 0)
- /*modified commented out: puts("md5 self-test completed successfully."); */
- return status;
-}
-
-/* Print the T values. */
-static int
-do_t_values(void) {
- int i;
- for (i = 1; i <= 64; ++i) {
- unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
-
- /*
- * The following nonsense is only to avoid compiler warnings about
- * "integer constant is unsigned in ANSI C, signed with -traditional".
- */
- if (v >> 31) {
- printf("#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\n", i,
- v, (unsigned long)(unsigned int)(~v));
- }
- else {
- printf("#define T%d 0x%08lx\n", i, v);
- }
- }
- return 0;
-}
-
-/* modified from original code changed function name main->md5main */
-/* Main program */
-int
-md5main(int argc, char *argv[]) {
- if (argc == 2) {
- if (!strcmp(argv[1], "--test"))
- return do_md5_test();
- if (!strcmp(argv[1], "--t-values"))
- return do_t_values();
- if (!strcmp(argv[1], "--version")) {
- puts(version);
- return 0;
- }
- }
- puts(usage);
- return 0;
-}
-
diff --git a/util/mmap.cpp b/util/mmap.cpp
deleted file mode 100644
index fa9ab735ef4..00000000000
--- a/util/mmap.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-// mmap.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "mmap.h"
-#include "processinfo.h"
-#include "concurrency/rwlock.h"
-#include "../db/namespace.h"
-#include "../db/cmdline.h"
-
-namespace mongo {
-
- set<MongoFile*> MongoFile::mmfiles;
- map<string,MongoFile*> MongoFile::pathToFile;
-
- /* Create. Must not exist.
- @param zero fill file with zeros when true
- */
- void* MemoryMappedFile::create(string filename, unsigned long long len, bool zero) {
- uassert( 13468, string("can't create file already exists ") + filename, !exists(filename) );
- void *p = map(filename.c_str(), len);
- if( p && zero ) {
- size_t sz = (size_t) len;
- assert( len == sz );
- memset(p, 0, sz);
- }
- return p;
- }
-
- /*static*/ void MemoryMappedFile::updateLength( const char *filename, unsigned long long &length ) {
- if ( !boost::filesystem::exists( filename ) )
- return;
- // make sure we map full length if preexisting file.
- boost::uintmax_t l = boost::filesystem::file_size( filename );
- length = l;
- }
-
- void* MemoryMappedFile::map(const char *filename) {
- unsigned long long l = boost::filesystem::file_size( filename );
- return map( filename , l );
- }
- void* MemoryMappedFile::mapWithOptions(const char *filename, int options) {
- unsigned long long l = boost::filesystem::file_size( filename );
- return map( filename , l, options );
- }
-
- /* --- MongoFile -------------------------------------------------
- this is the administrative stuff
- */
-
- RWLockRecursive MongoFile::mmmutex("mmmutex",10*60*1000 /* 10 minutes */);
-
- /* subclass must call in destructor (or at close).
- removes this from pathToFile and other maps
- safe to call more than once, albeit might be wasted work
- ideal to call close to the close, if the close is well before object destruction
- */
- void MongoFile::destroyed() {
- mmmutex.assertExclusivelyLocked();
- mmfiles.erase(this);
- pathToFile.erase( filename() );
- }
-
- /*static*/
- void MongoFile::closeAllFiles( stringstream &message ) {
- static int closingAllFiles = 0;
- if ( closingAllFiles ) {
- message << "warning closingAllFiles=" << closingAllFiles << endl;
- return;
- }
- ++closingAllFiles;
-
- RWLockRecursive::Exclusive lk(mmmutex);
-
- ProgressMeter pm( mmfiles.size() , 2 , 1 );
- set<MongoFile*> temp = mmfiles;
- for ( set<MongoFile*>::iterator i = temp.begin(); i != temp.end(); i++ ) {
- (*i)->close(); // close() now removes from mmfiles
- pm.hit();
- }
- message << "closeAllFiles() finished";
- --closingAllFiles;
- }
-
- /*static*/ long long MongoFile::totalMappedLength() {
- unsigned long long total = 0;
-
- RWLockRecursive::Shared lk(mmmutex);
- for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ )
- total += (*i)->length();
-
- return total;
- }
-
- void nullFunc() { }
-
- // callback notifications
- void (*MongoFile::notifyPreFlush)() = nullFunc;
- void (*MongoFile::notifyPostFlush)() = nullFunc;
-
- /*static*/ int MongoFile::flushAll( bool sync ) {
- notifyPreFlush();
- int x = _flushAll(sync);
- notifyPostFlush();
- return x;
- }
-
- /*static*/ int MongoFile::_flushAll( bool sync ) {
- if ( ! sync ) {
- int num = 0;
- RWLockRecursive::Shared lk(mmmutex);
- for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) {
- num++;
- MongoFile * mmf = *i;
- if ( ! mmf )
- continue;
-
- mmf->flush( sync );
- }
- return num;
- }
-
- // want to do it sync
- set<MongoFile*> seen;
- while ( true ) {
- auto_ptr<Flushable> f;
- {
- RWLockRecursive::Shared lk(mmmutex);
- for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) {
- MongoFile * mmf = *i;
- if ( ! mmf )
- continue;
- if ( seen.count( mmf ) )
- continue;
- f.reset( mmf->prepareFlush() );
- seen.insert( mmf );
- break;
- }
- }
- if ( ! f.get() )
- break;
-
- f->flush();
- }
- return seen.size();
- }
-
- void MongoFile::created() {
- RWLockRecursive::Exclusive lk(mmmutex);
- mmfiles.insert(this);
- }
-
- void MongoFile::setFilename(string fn) {
- RWLockRecursive::Exclusive lk(mmmutex);
- assert( _filename.empty() );
- _filename = fn;
- MongoFile *&ptf = pathToFile[fn];
- massert(13617, "MongoFile : multiple opens of same filename", ptf == 0);
- ptf = this;
- }
-
-#if defined(_DEBUG)
- void MongoFile::markAllWritable() {
- if( cmdLine.dur )
- return;
- RWLockRecursive::Shared lk(mmmutex);
- for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) {
- MongoFile * mmf = *i;
- if (mmf) mmf->_lock();
- }
- }
-
- void MongoFile::unmarkAllWritable() {
- if( cmdLine.dur )
- return;
- RWLockRecursive::Shared lk(mmmutex);
- for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ ) {
- MongoFile * mmf = *i;
- if (mmf) mmf->_unlock();
- }
- }
-#endif
-} // namespace mongo
diff --git a/util/mmap.h b/util/mmap.h
deleted file mode 100644
index 2bb9c160249..00000000000
--- a/util/mmap.h
+++ /dev/null
@@ -1,280 +0,0 @@
-// mmap.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <boost/thread/xtime.hpp>
-#include "concurrency/rwlock.h"
-
-namespace mongo {
-
- class MAdvise {
- void *_p;
- unsigned _len;
- public:
- enum Advice { Sequential=1 };
- MAdvise(void *p, unsigned len, Advice a);
- ~MAdvise(); // destructor resets the range to MADV_NORMAL
- };
-
- /* the administrative-ish stuff here */
- class MongoFile : boost::noncopyable {
- public:
- /** Flushable has to fail nicely if the underlying object gets killed */
- class Flushable {
- public:
- virtual ~Flushable() {}
- virtual void flush() = 0;
- };
-
- virtual ~MongoFile() {}
-
- enum Options {
- SEQUENTIAL = 1, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on windows
- READONLY = 2 // not contractually guaranteed, but if specified the impl has option to fault writes
- };
-
- /** @param fun is called for each MongoFile.
- calledl from within a mutex that MongoFile uses. so be careful not to deadlock.
- */
- template < class F >
- static void forEach( F fun );
-
- /** note: you need to be in mmmutex when using this. forEach (above) handles that for you automatically.
-*/
- static set<MongoFile*>& getAllFiles() { return mmfiles; }
-
- // callbacks if you need them
- static void (*notifyPreFlush)();
- static void (*notifyPostFlush)();
-
- static int flushAll( bool sync ); // returns n flushed
- static long long totalMappedLength();
- static void closeAllFiles( stringstream &message );
-
-#if defined(_DEBUG)
- static void markAllWritable();
- static void unmarkAllWritable();
-#else
- static void markAllWritable() { }
- static void unmarkAllWritable() { }
-#endif
-
- static bool exists(boost::filesystem::path p) { return boost::filesystem::exists(p); }
-
- virtual bool isMongoMMF() { return false; }
-
- string filename() const { return _filename; }
- void setFilename(string fn);
-
- private:
- string _filename;
- static int _flushAll( bool sync ); // returns n flushed
- protected:
- virtual void close() = 0;
- virtual void flush(bool sync) = 0;
- /**
- * returns a thread safe object that you can call flush on
- * Flushable has to fail nicely if the underlying object gets killed
- */
- virtual Flushable * prepareFlush() = 0;
-
- void created(); /* subclass must call after create */
-
- /* subclass must call in destructor (or at close).
- removes this from pathToFile and other maps
- safe to call more than once, albeit might be wasted work
- ideal to call close to the close, if the close is well before object destruction
- */
- void destroyed();
-
- virtual unsigned long long length() const = 0;
-
- // only supporting on posix mmap
- virtual void _lock() {}
- virtual void _unlock() {}
-
- static set<MongoFile*> mmfiles;
- public:
- static map<string,MongoFile*> pathToFile;
-
- // lock order: lock dbMutex before this if you lock both
- static RWLockRecursive mmmutex;
- };
-
- /** look up a MMF by filename. scoped mutex locking convention.
- example:
- MMFFinderByName finder;
- MongoMMF *a = finder.find("file_name_a");
- MongoMMF *b = finder.find("file_name_b");
- */
- class MongoFileFinder : boost::noncopyable {
- public:
- MongoFileFinder() : _lk(MongoFile::mmmutex) { }
-
- /** @return The MongoFile object associated with the specified file name. If no file is open
- with the specified name, returns null.
- */
- MongoFile* findByPath(string path) {
- map<string,MongoFile*>::iterator i = MongoFile::pathToFile.find(path);
- return i == MongoFile::pathToFile.end() ? NULL : i->second;
- }
-
- private:
- RWLockRecursive::Shared _lk;
- };
-
- struct MongoFileAllowWrites {
- MongoFileAllowWrites() {
- MongoFile::markAllWritable();
- }
- ~MongoFileAllowWrites() {
- MongoFile::unmarkAllWritable();
- }
- };
-
- class MemoryMappedFile : public MongoFile {
- protected:
- virtual void* viewForFlushing() {
- if( views.size() == 0 )
- return 0;
- assert( views.size() == 1 );
- return views[0];
- }
- public:
- MemoryMappedFile();
-
- virtual ~MemoryMappedFile() {
- RWLockRecursive::Exclusive lk(mmmutex);
- close();
- }
-
- virtual void close();
-
- // Throws exception if file doesn't exist. (dm may2010: not sure if this is always true?)
- void* map(const char *filename);
-
- /** @param options see MongoFile::Options */
- void* mapWithOptions(const char *filename, int options);
-
- /* Creates with length if DNE, otherwise uses existing file length,
- passed length.
- @param options MongoFile::Options bits
- */
- void* map(const char *filename, unsigned long long &length, int options = 0 );
-
- /* Create. Must not exist.
- @param zero fill file with zeros when true
- */
- void* create(string filename, unsigned long long len, bool zero);
-
- void flush(bool sync);
- virtual Flushable * prepareFlush();
-
- long shortLength() const { return (long) len; }
- unsigned long long length() const { return len; }
-
- /** create a new view with the specified properties.
- automatically cleaned up upon close/destruction of the MemoryMappedFile object.
- */
- void* createReadOnlyMap();
- void* createPrivateMap();
-
- /** make the private map range writable (necessary for our windows implementation) */
- static void makeWritable(void *, unsigned len)
-#if defined(_WIN32)
- ;
-#else
- { }
-#endif
-
- private:
- static void updateLength( const char *filename, unsigned long long &length );
-
- HANDLE fd;
- HANDLE maphandle;
- vector<void *> views;
- unsigned long long len;
-
-#ifdef _WIN32
- boost::shared_ptr<mutex> _flushMutex;
- void clearWritableBits(void *privateView);
- public:
- static const unsigned ChunkSize = 64 * 1024 * 1024;
- static const unsigned NChunks = 1024 * 1024;
-#else
- void clearWritableBits(void *privateView) { }
-#endif
-
- protected:
- // only posix mmap implementations will support this
- virtual void _lock();
- virtual void _unlock();
-
- /** close the current private view and open a new replacement */
- void* remapPrivateView(void *oldPrivateAddr);
- };
-
- typedef MemoryMappedFile MMF;
-
- /** p is called from within a mutex that MongoFile uses. so be careful not to deadlock. */
- template < class F >
- inline void MongoFile::forEach( F p ) {
- RWLockRecursive::Shared lklk(mmmutex);
- for ( set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++ )
- p(*i);
- }
-
-#if defined(_WIN32)
- class ourbitset {
- volatile unsigned bits[MemoryMappedFile::NChunks]; // volatile as we are doing double check locking
- public:
- ourbitset() {
- memset((void*) bits, 0, sizeof(bits));
- }
- bool get(unsigned i) const {
- unsigned x = i / 32;
- assert( x < MemoryMappedFile::NChunks );
- return (bits[x] & (1 << (i%32))) != 0;
- }
- void set(unsigned i) {
- unsigned x = i / 32;
- wassert( x < (MemoryMappedFile::NChunks*2/3) ); // warn if getting close to limit
- assert( x < MemoryMappedFile::NChunks );
- bits[x] |= (1 << (i%32));
- }
- void clear(unsigned i) {
- unsigned x = i / 32;
- assert( x < MemoryMappedFile::NChunks );
- bits[x] &= ~(1 << (i%32));
- }
- };
- extern ourbitset writable;
- void makeChunkWritable(size_t chunkno);
- inline void MemoryMappedFile::makeWritable(void *_p, unsigned len) {
- size_t p = (size_t) _p;
- unsigned a = p/ChunkSize;
- unsigned b = (p+len)/ChunkSize;
- for( unsigned i = a; i <= b; i++ ) {
- if( !writable.get(i) ) {
- makeChunkWritable(i);
- }
- }
- }
- extern void* getNextMemoryMappedFileLocation( unsigned long long mmfSize );
-#endif
-
-} // namespace mongo
diff --git a/util/mmap_mm.cpp b/util/mmap_mm.cpp
deleted file mode 100644
index ec2400e02d3..00000000000
--- a/util/mmap_mm.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// mmap_mm.cpp - in memory (no file) version
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "mmap.h"
-
-/* in memory (no file) version */
-
-namespace mongo {
-
- MemoryMappedFile::MemoryMappedFile() {
- fd = 0;
- maphandle = 0;
- view = 0;
- len = 0;
- }
-
- void MemoryMappedFile::close() {
- if ( view )
- free( view );
- view = 0;
- len = 0;
- }
-
- void* MemoryMappedFile::map(const char *filename, long& length , int options ) {
- assert( length );
- view = malloc( length );
- return view;
- }
-
- void MemoryMappedFile::flush(bool sync) {
- }
-
- void MemoryMappedFile::_lock() {}
- void MemoryMappedFile::_unlock() {}
-
-}
-
diff --git a/util/mmap_posix.cpp b/util/mmap_posix.cpp
deleted file mode 100644
index 5b5e86d7c0c..00000000000
--- a/util/mmap_posix.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-// mmap_posix.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "mmap.h"
-#include "file_allocator.h"
-#include "../db/concurrency.h"
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include "../util/processinfo.h"
-#include "mongoutils/str.h"
-using namespace mongoutils;
-
-namespace mongo {
-
- MemoryMappedFile::MemoryMappedFile() {
- fd = 0;
- maphandle = 0;
- len = 0;
- created();
- }
-
- void MemoryMappedFile::close() {
- mmmutex.assertExclusivelyLocked();
- for( vector<void*>::iterator i = views.begin(); i != views.end(); i++ ) {
- munmap(*i,len);
- }
- views.clear();
-
- if ( fd )
- ::close(fd);
- fd = 0;
- destroyed(); // cleans up from the master list of mmaps
- }
-
-#ifndef O_NOATIME
-#define O_NOATIME (0)
-#endif
-
-#ifndef MAP_NORESERVE
-#define MAP_NORESERVE (0)
-#endif
-
-#if defined(__sunos__)
- MAdvise::MAdvise(void *,unsigned, Advice) { }
- MAdvise::~MAdvise() { }
-#else
- MAdvise::MAdvise(void *p, unsigned len, Advice a) : _p(p), _len(len) {
- assert( a == Sequential ); // more later
- madvise(_p,_len,MADV_SEQUENTIAL);
- }
- MAdvise::~MAdvise() {
- madvise(_p,_len,MADV_NORMAL);
- }
-#endif
-
- void* MemoryMappedFile::map(const char *filename, unsigned long long &length, int options) {
- // length may be updated by callee.
- setFilename(filename);
- FileAllocator::get()->allocateAsap( filename, length );
- len = length;
-
- massert( 10446 , str::stream() << "mmap: can't map area of size 0 file: " << filename, length > 0 );
-
- fd = open(filename, O_RDWR | O_NOATIME);
- if ( fd <= 0 ) {
- log() << "couldn't open " << filename << ' ' << errnoWithDescription() << endl;
- fd = 0; // our sentinel for not opened
- return 0;
- }
-
- unsigned long long filelen = lseek(fd, 0, SEEK_END);
- uassert(10447, str::stream() << "map file alloc failed, wanted: " << length << " filelen: " << filelen << ' ' << sizeof(size_t), filelen == length );
- lseek( fd, 0, SEEK_SET );
-
- void * view = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if ( view == MAP_FAILED ) {
- error() << " mmap() failed for " << filename << " len:" << length << " " << errnoWithDescription() << endl;
- if ( errno == ENOMEM ) {
- if( sizeof(void*) == 4 )
- error() << "mmap failed with out of memory. You are using a 32-bit build and probably need to upgrade to 64" << endl;
- else
- error() << "mmap failed with out of memory. (64 bit build)" << endl;
- }
- return 0;
- }
-
-
-#if defined(__sunos__)
-#warning madvise not supported on solaris yet
-#else
- if ( options & SEQUENTIAL ) {
- if ( madvise( view , length , MADV_SEQUENTIAL ) ) {
- warning() << "map: madvise failed for " << filename << ' ' << errnoWithDescription() << endl;
- }
- }
-#endif
-
- views.push_back( view );
-
- DEV if (! dbMutex.info().isLocked()) {
- _unlock();
- }
-
- return view;
- }
-
- void* MemoryMappedFile::createReadOnlyMap() {
- void * x = mmap( /*start*/0 , len , PROT_READ , MAP_SHARED , fd , 0 );
- if( x == MAP_FAILED ) {
- if ( errno == ENOMEM ) {
- if( sizeof(void*) == 4 )
- error() << "mmap ro failed with out of memory. You are using a 32-bit build and probably need to upgrade to 64" << endl;
- else
- error() << "mmap ro failed with out of memory. (64 bit build)" << endl;
- }
- return 0;
- }
- return x;
- }
-
- void* MemoryMappedFile::createPrivateMap() {
- void * x = mmap( /*start*/0 , len , PROT_READ|PROT_WRITE , MAP_PRIVATE|MAP_NORESERVE , fd , 0 );
- if( x == MAP_FAILED ) {
- if ( errno == ENOMEM ) {
- if( sizeof(void*) == 4 ) {
- error() << "mmap private failed with out of memory. You are using a 32-bit build and probably need to upgrade to 64" << endl;
- }
- else {
- error() << "mmap private failed with out of memory. (64 bit build)" << endl;
- }
- }
- else {
- error() << "mmap private failed " << errnoWithDescription() << endl;
- }
- return 0;
- }
-
- views.push_back(x);
- return x;
- }
-
- void* MemoryMappedFile::remapPrivateView(void *oldPrivateAddr) {
- // don't unmap, just mmap over the old region
- void * x = mmap( oldPrivateAddr, len , PROT_READ|PROT_WRITE , MAP_PRIVATE|MAP_NORESERVE|MAP_FIXED , fd , 0 );
- if( x == MAP_FAILED ) {
- int err = errno;
- error() << "13601 Couldn't remap private view: " << errnoWithDescription(err) << endl;
- log() << "aborting" << endl;
- printMemInfo();
- abort();
- }
- assert( x == oldPrivateAddr );
- return x;
- }
-
- void MemoryMappedFile::flush(bool sync) {
- if ( views.empty() || fd == 0 )
- return;
- if ( msync(viewForFlushing(), len, sync ? MS_SYNC : MS_ASYNC) )
- problem() << "msync " << errnoWithDescription() << endl;
- }
-
- class PosixFlushable : public MemoryMappedFile::Flushable {
- public:
- PosixFlushable( void * view , HANDLE fd , long len )
- : _view( view ) , _fd( fd ) , _len(len) {
- }
-
- void flush() {
- if ( _view && _fd )
- if ( msync(_view, _len, MS_SYNC ) )
- problem() << "msync " << errnoWithDescription() << endl;
-
- }
-
- void * _view;
- HANDLE _fd;
- long _len;
- };
-
- MemoryMappedFile::Flushable * MemoryMappedFile::prepareFlush() {
- return new PosixFlushable( viewForFlushing() , fd , len );
- }
-
- void MemoryMappedFile::_lock() {
- if (! views.empty() && isMongoMMF() )
- assert(mprotect(views[0], len, PROT_READ | PROT_WRITE) == 0);
- }
-
- void MemoryMappedFile::_unlock() {
- if (! views.empty() && isMongoMMF() )
- assert(mprotect(views[0], len, PROT_READ) == 0);
- }
-
-} // namespace mongo
-
diff --git a/util/mmap_win.cpp b/util/mmap_win.cpp
deleted file mode 100644
index f17e0a26848..00000000000
--- a/util/mmap_win.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-// mmap_win.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "mmap.h"
-#include "text.h"
-#include "../db/mongommf.h"
-#include "../db/concurrency.h"
-#include "timer.h"
-
-namespace mongo {
-
- mutex mapViewMutex("mapView");
- ourbitset writable;
-
- MAdvise::MAdvise(void *,unsigned, Advice) { }
- MAdvise::~MAdvise() { }
-
- static unsigned long long _nextMemoryMappedFileLocation = 256LL * 1024LL * 1024LL * 1024LL;
- static SimpleMutex _nextMemoryMappedFileLocationMutex( "nextMemoryMappedFileLocationMutex" );
-
- void* getNextMemoryMappedFileLocation( unsigned long long mmfSize ) {
- if ( 4 == sizeof(void*) ) {
- return 0;
- }
- SimpleMutex::scoped_lock lk( _nextMemoryMappedFileLocationMutex );
- static unsigned long long granularity = 0;
- if ( 0 == granularity ) {
- SYSTEM_INFO systemInfo;
- GetSystemInfo( &systemInfo );
- granularity = static_cast<unsigned long long>( systemInfo.dwAllocationGranularity );
- }
- unsigned long long thisMemoryMappedFileLocation = _nextMemoryMappedFileLocation;
- mmfSize = ( mmfSize + granularity - 1) & ~( granularity - 1 );
- _nextMemoryMappedFileLocation += mmfSize;
- return reinterpret_cast<void*>( static_cast<uintptr_t>( thisMemoryMappedFileLocation ) );
- }
-
- /** notification on unmapping so we can clear writable bits */
- void MemoryMappedFile::clearWritableBits(void *p) {
- for( unsigned i = ((size_t)p)/ChunkSize; i <= (((size_t)p)+len)/ChunkSize; i++ ) {
- writable.clear(i);
- assert( !writable.get(i) );
- }
- }
-
- MemoryMappedFile::MemoryMappedFile()
- : _flushMutex(new mutex("flushMutex")) {
- fd = 0;
- maphandle = 0;
- len = 0;
- created();
- }
-
- void MemoryMappedFile::close() {
- mmmutex.assertExclusivelyLocked();
- for( vector<void*>::iterator i = views.begin(); i != views.end(); i++ ) {
- clearWritableBits(*i);
- UnmapViewOfFile(*i);
- }
- views.clear();
- if ( maphandle )
- CloseHandle(maphandle);
- maphandle = 0;
- if ( fd )
- CloseHandle(fd);
- fd = 0;
- destroyed(); // cleans up from the master list of mmaps
- }
-
- unsigned long long mapped = 0;
-
- void* MemoryMappedFile::createReadOnlyMap() {
- assert( maphandle );
- scoped_lock lk(mapViewMutex);
- LPVOID thisAddress = getNextMemoryMappedFileLocation( len );
- void* readOnlyMapAddress = MapViewOfFileEx(
- maphandle, // file mapping handle
- FILE_MAP_READ, // access
- 0, 0, // file offset, high and low
- 0, // bytes to map, 0 == all
- thisAddress ); // address to place file
- if ( 0 == readOnlyMapAddress ) {
- DWORD dosError = GetLastError();
- log() << "MapViewOfFileEx for " << filename()
- << " failed with " << errnoWithDescription( dosError )
- << " (file size is " << len << ")"
- << " in MemoryMappedFile::createReadOnlyMap, terminating"
- << endl;
- ::abort();
- }
- views.push_back( readOnlyMapAddress );
- return readOnlyMapAddress;
- }
-
- void* MemoryMappedFile::map(const char *filenameIn, unsigned long long &length, int options) {
- assert( fd == 0 && len == 0 ); // can't open more than once
- setFilename(filenameIn);
- /* big hack here: Babble uses db names with colons. doesn't seem to work on windows. temporary perhaps. */
- char filename[256];
- strncpy(filename, filenameIn, 255);
- filename[255] = 0;
- {
- size_t len = strlen( filename );
- for ( size_t i=len-1; i>=0; i-- ) {
- if ( filename[i] == '/' ||
- filename[i] == '\\' )
- break;
-
- if ( filename[i] == ':' )
- filename[i] = '_';
- }
- }
-
- updateLength( filename, length );
-
- {
- DWORD createOptions = FILE_ATTRIBUTE_NORMAL;
- if ( options & SEQUENTIAL )
- createOptions |= FILE_FLAG_SEQUENTIAL_SCAN;
- DWORD rw = GENERIC_READ | GENERIC_WRITE;
- fd = CreateFile(
- toNativeString(filename).c_str(),
- rw, // desired access
- FILE_SHARE_WRITE | FILE_SHARE_READ, // share mode
- NULL, // security
- OPEN_ALWAYS, // create disposition
- createOptions , // flags
- NULL); // hTempl
- if ( fd == INVALID_HANDLE_VALUE ) {
- DWORD e = GetLastError();
- log() << "Create/OpenFile failed " << filename << " errno:" << e << endl;
- return 0;
- }
- }
-
- mapped += length;
-
- {
- DWORD flProtect = PAGE_READWRITE; //(options & READONLY)?PAGE_READONLY:PAGE_READWRITE;
- maphandle = CreateFileMapping(fd, NULL, flProtect,
- length >> 32 /*maxsizehigh*/,
- (unsigned) length /*maxsizelow*/,
- NULL/*lpName*/);
- if ( maphandle == NULL ) {
- DWORD e = GetLastError(); // log() call was killing lasterror before we get to that point in the stream
- log() << "CreateFileMapping failed " << filename << ' ' << errnoWithDescription(e) << endl;
- close();
- return 0;
- }
- }
-
- void *view = 0;
- {
- scoped_lock lk(mapViewMutex);
- DWORD access = ( options & READONLY ) ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS;
- LPVOID thisAddress = getNextMemoryMappedFileLocation( length );
- view = MapViewOfFileEx(
- maphandle, // file mapping handle
- access, // access
- 0, 0, // file offset, high and low
- 0, // bytes to map, 0 == all
- thisAddress ); // address to place file
- }
- {
- if ( view == 0 ) {
- DWORD dosError = GetLastError();
- log() << "MapViewOfFileEx for " << filename
- << " failed with " << errnoWithDescription( dosError )
- << " (file size is " << length << ")"
- << " in MemoryMappedFile::map, terminating"
- << endl;
- close();
- ::abort();
- }
- }
- views.push_back(view);
- len = length;
-
- return view;
- }
-
- class WindowsFlushable : public MemoryMappedFile::Flushable {
- public:
- WindowsFlushable( void * view , HANDLE fd , string filename , boost::shared_ptr<mutex> flushMutex )
- : _view(view) , _fd(fd) , _filename(filename) , _flushMutex(flushMutex)
- {}
-
- void flush() {
- if (!_view || !_fd)
- return;
-
- scoped_lock lk(*_flushMutex);
-
- int loopCount = 0;
- bool success = false;
- bool timeout = false;
- int dosError = ERROR_SUCCESS;
- const int maximumTimeInSeconds = 60 * 15;
- Timer t;
- while ( !success && !timeout ) {
- ++loopCount;
- success = FALSE != FlushViewOfFile( _view, 0 );
- if ( !success ) {
- dosError = GetLastError();
- if ( dosError != ERROR_LOCK_VIOLATION ) {
- break;
- }
- timeout = t.seconds() > maximumTimeInSeconds;
- }
- }
- if ( success && loopCount > 1 ) {
- log() << "FlushViewOfFile for " << _filename
- << " succeeded after " << loopCount
- << " attempts taking " << t.millis()
- << " ms" << endl;
- }
- else if ( !success ) {
- log() << "FlushViewOfFile for " << _filename
- << " failed with error " << dosError
- << " after " << loopCount
- << " attempts taking " << t.millis()
- << " ms" << endl;
- // Abort here to avoid data corruption
- abort();
- }
-
- success = FALSE != FlushFileBuffers(_fd);
- if (!success) {
- int err = GetLastError();
- out() << "FlushFileBuffers failed " << err << " file: " << _filename << endl;
- }
- }
-
- void * _view;
- HANDLE _fd;
- string _filename;
- boost::shared_ptr<mutex> _flushMutex;
- };
-
- void MemoryMappedFile::flush(bool sync) {
- uassert(13056, "Async flushing not supported on windows", sync);
- if( !views.empty() ) {
- WindowsFlushable f( viewForFlushing() , fd , filename() , _flushMutex);
- f.flush();
- }
- }
-
- MemoryMappedFile::Flushable * MemoryMappedFile::prepareFlush() {
- return new WindowsFlushable( viewForFlushing() , fd , filename() , _flushMutex );
- }
- void MemoryMappedFile::_lock() {}
- void MemoryMappedFile::_unlock() {}
-
-}
diff --git a/util/mongoutils/README b/util/mongoutils/README
deleted file mode 100755
index f61277c7409..00000000000
--- a/util/mongoutils/README
+++ /dev/null
@@ -1,15 +0,0 @@
- mongoutils namespace requirements:
-
- (1) code is not database specific, rather, true utilities
- (2) are cross platform
- (3) may require boost headers, but not libs
- (4) are clean and easy to use in any c++ project without pulling in lots of other stuff.
- specifically, does not use anything in the mongo namespace!
- (5) apache license
- (6) must be documented! if you aren't going to bother (but don't do that), stick it in util.
- (7) ideally header only (in the spirit of #3)
-
- So basically, easy to use, general purpose stuff, with no arduous dependencies to drop into
- any new project.
-
- *** PLACE UNIT TESTS IN mongoutils/test.cpp ***
diff --git a/util/mongoutils/checksum.h b/util/mongoutils/checksum.h
deleted file mode 100644
index ea3d05131ce..00000000000
--- a/util/mongoutils/checksum.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/** @file checksum.h */
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongoutils {
-
- /**
- * this is a silly temporary implementation
- */
- inline int checksum( const char* x , int size ) {
- int ck = 0;
- for ( int i=0; i<size; i++ )
- ck += ( (int)x[i] * ( i + 1 ) );
- return ck;
- }
-
-}
diff --git a/util/mongoutils/hash.h b/util/mongoutils/hash.h
deleted file mode 100644
index 49f30b3242a..00000000000
--- a/util/mongoutils/hash.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/** @file hash.h */
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongoutils {
-
- /** @return hash of a pointer to an unsigned. so you get a 32 bit hash out, regardless of whether
- pointers are 32 or 64 bit on the particular platform.
-
- is there a faster way to impl this that hashes just as well?
- */
- inline unsigned hashPointer(void *v) {
- unsigned x = 0;
- unsigned char *p = (unsigned char *) &v;
- for( unsigned i = 0; i < sizeof(void*); i++ ) {
- x = x * 131 + p[i];
- }
- return x;
- }
-
- inline unsigned hash(unsigned u) {
- unsigned char *p = (unsigned char *) &u;
- return (((((p[3] * 131) + p[2]) * 131) + p[1]) * 131) + p[0];
- }
-
-}
diff --git a/util/mongoutils/html.h b/util/mongoutils/html.h
deleted file mode 100644
index f79e6ca514f..00000000000
--- a/util/mongoutils/html.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// @file html.h
-
-#pragma once
-
-/* Things in the mongoutils namespace
- (1) are not database specific, rather, true utilities
- (2) are cross platform
- (3) may require boost headers, but not libs
- (4) are clean and easy to use in any c++ project without pulling in lots of other stuff
-*/
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sstream>
-
-namespace mongoutils {
-
- namespace html {
-
- using namespace std;
-
- inline string _end() { return "</body></html>"; }
- inline string _table() { return "</table>\n\n"; }
- inline string _tr() { return "</tr>\n"; }
-
- inline string tr() { return "<tr>"; }
- inline string tr(string a, string b) {
- stringstream ss;
- ss << "<tr><td>" << a << "</td><td>" << b << "</td></tr>\n";
- return ss.str();
- }
- template <class T>
- inline string td(T x) {
- stringstream ss;
- ss << "<td>" << x << "</td>";
- return ss.str();
- }
- inline string td(string x) {
- return "<td>" + x + "</td>";
- }
- inline string th(string x) {
- return "<th>" + x + "</th>";
- }
-
- inline void tablecell( stringstream& ss , bool b ) {
- ss << "<td>" << (b ? "<b>X</b>" : "") << "</td>";
- }
-
- template< typename T>
- inline void tablecell( stringstream& ss , const T& t ) {
- ss << "<td>" << t << "</td>";
- }
-
- inline string table(const char *headers[] = 0, bool border = true) {
- stringstream ss;
- ss << "\n<table "
- << (border?"border=1 ":"")
- << "cellpadding=2 cellspacing=0>\n";
- if( headers ) {
- ss << "<tr>";
- while( *headers ) {
- ss << "<th>" << *headers << "</th>";
- headers++;
- }
- ss << "</tr>\n";
- }
- return ss.str();
- }
-
- inline string start(string title) {
- stringstream ss;
- ss << "<html><head>\n<title>";
- ss << title;
- ss << "</title>\n";
-
- ss << "<style type=\"text/css\" media=\"screen\">"
- "body { font-family: helvetica, arial, san-serif }\n"
- "table { border-collapse:collapse; border-color:#999; margin-top:.5em }\n"
- "th { background-color:#bbb; color:#000 }\n"
- "td,th { padding:.25em }\n"
- "</style>\n";
-
- ss << "</head>\n<body>\n";
- return ss.str();
- }
-
- inline string red(string contentHtml, bool color=true) {
- if( !color ) return contentHtml;
- stringstream ss;
- ss << "<span style=\"color:#A00;\">" << contentHtml << "</span>";
- return ss.str();
- }
- inline string grey(string contentHtml, bool color=true) {
- if( !color ) return contentHtml;
- stringstream ss;
- ss << "<span style=\"color:#888;\">" << contentHtml << "</span>";
- return ss.str();
- }
- inline string blue(string contentHtml, bool color=true) {
- if( !color ) return contentHtml;
- stringstream ss;
- ss << "<span style=\"color:#00A;\">" << contentHtml << "</span>";
- return ss.str();
- }
- inline string yellow(string contentHtml, bool color=true) {
- if( !color ) return contentHtml;
- stringstream ss;
- ss << "<span style=\"color:#A80;\">" << contentHtml << "</span>";
- return ss.str();
- }
- inline string green(string contentHtml, bool color=true) {
- if( !color ) return contentHtml;
- stringstream ss;
- ss << "<span style=\"color:#0A0;\">" << contentHtml << "</span>";
- return ss.str();
- }
-
- inline string p(string contentHtml) {
- stringstream ss;
- ss << "<p>" << contentHtml << "</p>\n";
- return ss.str();
- }
-
- inline string h2(string contentHtml) {
- stringstream ss;
- ss << "<h2>" << contentHtml << "</h2>\n";
- return ss.str();
- }
-
- /* does NOT escape the strings. */
- inline string a(string href, string title="", string contentHtml = "") {
- stringstream ss;
- ss << "<a";
- if( !href.empty() ) ss << " href=\"" << href << '"';
- if( !title.empty() ) ss << " title=\"" << title << '"';
- ss << '>';
- if( !contentHtml.empty() ) {
- ss << contentHtml << "</a>";
- }
- return ss.str();
- }
-
- }
-
-}
diff --git a/util/mongoutils/mongoutils.vcxproj b/util/mongoutils/mongoutils.vcxproj
deleted file mode 100755
index f6ec0935ca9..00000000000
--- a/util/mongoutils/mongoutils.vcxproj
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{7B84584E-92BC-4DB9-971B-A1A8F93E5053}</ProjectGuid>
- <RootNamespace>mongoutils</RootNamespace>
- <ProjectName>mongoutils test program</ProjectName>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>MultiByte</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>MultiByte</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup />
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>c:\boost;\boost</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <AdditionalIncludeDirectories>c:\boost;\boost</AdditionalIncludeDirectories>
- </ClCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="test.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="html.h" />
- <ClInclude Include="str.h" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/util/mongoutils/mongoutils.vcxproj.filters b/util/mongoutils/mongoutils.vcxproj.filters
deleted file mode 100755
index 84ecbffede0..00000000000
--- a/util/mongoutils/mongoutils.vcxproj.filters
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <ClCompile Include="test.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="html.h" />
- <ClInclude Include="str.h" />
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/util/mongoutils/str.h b/util/mongoutils/str.h
deleted file mode 100644
index 57b94fadd48..00000000000
--- a/util/mongoutils/str.h
+++ /dev/null
@@ -1,208 +0,0 @@
-// @file str.h
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-/* Things in the mongoutils namespace
- (1) are not database specific, rather, true utilities
- (2) are cross platform
- (3) may require boost headers, but not libs
- (4) are clean and easy to use in any c++ project without pulling in lots of other stuff
-
- Note: within this module, we use int for all offsets -- there are no unsigned offsets
- and no size_t's. If you need 3 gigabyte long strings, don't use this module.
-*/
-
-#include <string>
-#include <sstream>
-
-// this violates the README rules for mongoutils:
-#include "../../bson/util/builder.h"
-
-namespace mongoutils {
-
- namespace str {
-
- typedef std::string string;
-
- /** the idea here is to make one liners easy. e.g.:
-
- return str::stream() << 1 << ' ' << 2;
-
- since the following doesn't work:
-
- (stringstream() << 1).str();
- */
- class stream {
- public:
- mongo::StringBuilder ss;
- template<class T>
- stream& operator<<(const T& v) {
- ss << v;
- return *this;
- }
- operator std::string () const { return ss.str(); }
- };
-
- inline bool startsWith(const char *str, const char *prefix) {
- const char *s = str;
- const char *p = prefix;
- while( *p ) {
- if( *p != *s ) return false;
- p++; s++;
- }
- return true;
- }
- inline bool startsWith(string s, string p) { return startsWith(s.c_str(), p.c_str()); }
-
- inline bool endsWith(string s, string p) {
- int l = p.size();
- int x = s.size();
- if( x < l ) return false;
- return strncmp(s.c_str()+x-l, p.c_str(), l) == 0;
- }
-
- inline bool equals( const char * a , const char * b ) { return strcmp( a , b ) == 0; }
-
- /** find char x, and return rest of string thereafter, or "" if not found */
- inline const char * after(const char *s, char x) {
- const char *p = strchr(s, x);
- return (p != 0) ? p+1 : "";
- }
- inline string after(const string& s, char x) {
- const char *p = strchr(s.c_str(), x);
- return (p != 0) ? string(p+1) : "";
- }
-
- /** find string x, and return rest of string thereafter, or "" if not found */
- inline const char * after(const char *s, const char *x) {
- const char *p = strstr(s, x);
- return (p != 0) ? p+strlen(x) : "";
- }
- inline string after(string s, string x) {
- const char *p = strstr(s.c_str(), x.c_str());
- return (p != 0) ? string(p+x.size()) : "";
- }
-
- /** @return true if s contains x */
- inline bool contains(string s, string x) {
- return strstr(s.c_str(), x.c_str()) != 0;
- }
- inline bool contains(string s, char x) {
- return strchr(s.c_str(), x) != 0;
- }
-
- /** @return everything before the character x, else entire string */
- inline string before(const string& s, char x) {
- const char *p = strchr(s.c_str(), x);
- return (p != 0) ? s.substr(0, p-s.c_str()) : s;
- }
-
- /** @return everything before the string x, else entire string */
- inline string before(const string& s, const string& x) {
- const char *p = strstr(s.c_str(), x.c_str());
- return (p != 0) ? s.substr(0, p-s.c_str()) : s;
- }
-
- /** check if if strings share a common starting prefix
- @return offset of divergence (or length if equal). 0=nothing in common. */
- inline int shareCommonPrefix(const char *p, const char *q) {
- int ofs = 0;
- while( 1 ) {
- if( *p == 0 || *q == 0 )
- break;
- if( *p != *q )
- break;
- p++; q++; ofs++;
- }
- return ofs;
- }
- inline int shareCommonPrefix(const string &a, const string &b)
- { return shareCommonPrefix(a.c_str(), b.c_str()); }
-
- /** string to unsigned. zero if not a number. can end with non-num chars */
- inline unsigned toUnsigned(const string& a) {
- unsigned x = 0;
- const char *p = a.c_str();
- while( 1 ) {
- if( !isdigit(*p) )
- break;
- x = x * 10 + (*p - '0');
- p++;
- }
- return x;
- }
-
- /** split a string on a specific char. We don't split N times, just once
- on the first occurrence. If char not present entire string is in L
- and R is empty.
- @return true if char found
- */
- inline bool splitOn(const string &s, char c, string& L, string& R) {
- const char *start = s.c_str();
- const char *p = strchr(start, c);
- if( p == 0 ) {
- L = s; R.clear();
- return false;
- }
- L = string(start, p-start);
- R = string(p+1);
- return true;
- }
- /** split scanning reverse direction. Splits ONCE ONLY. */
- inline bool rSplitOn(const string &s, char c, string& L, string& R) {
- const char *start = s.c_str();
- const char *p = strrchr(start, c);
- if( p == 0 ) {
- L = s; R.clear();
- return false;
- }
- L = string(start, p-start);
- R = string(p+1);
- return true;
- }
-
- /** @return number of occurrences of c in s */
- inline unsigned count( const string& s , char c ) {
- unsigned n=0;
- for ( unsigned i=0; i<s.size(); i++ )
- if ( s[i] == c )
- n++;
- return n;
- }
-
- /** trim leading spaces. spaces only, not tabs etc. */
- inline string ltrim(const string& s) {
- const char *p = s.c_str();
- while( *p == ' ' ) p++;
- return p;
- }
-
- /** remove trailing chars in place */
- inline void stripTrailing(string& s, const char *chars) {
- string::iterator i = s.end();
- while( s.begin() != i ) {
- i--;
- if( contains(chars, *i) ) {
- s.erase(i);
- }
- }
- }
-
- }
-
-}
diff --git a/util/mongoutils/test.cpp b/util/mongoutils/test.cpp
deleted file mode 100644
index 45268c5ca49..00000000000
--- a/util/mongoutils/test.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/* @file test.cpp
- utils/mongoutils/test.cpp
- unit tests for mongoutils
-*/
-
-/*
- * Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <assert.h>
-#include "str.h"
-#include "html.h"
-
-using namespace std;
-using namespace mongoutils;
-
-int main() {
- {
- string s = "abcde";
- str::stripTrailing(s, "ef");
- assert( s == "abcd" );
- str::stripTrailing(s, "abcd");
- assert( s.empty() );
- s = "abcddd";
- str::stripTrailing(s, "d");
- assert( s == "abc" );
- }
-
- string x = str::after("abcde", 'c');
- assert( x == "de" );
- assert( str::after("abcde", 'x') == "" );
- return 0;
-}
diff --git a/util/moveablebuffer.h b/util/moveablebuffer.h
deleted file mode 100644
index e01f2d8d9a4..00000000000
--- a/util/moveablebuffer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* moveablebuffer.h
-*/
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
-
- /** this is a sort of smart pointer class where we can move where something is and all the pointers will adjust.
- not threadsafe.
- */
- struct MoveableBuffer {
- MoveableBuffer();
- MoveableBuffer(void *);
- MoveableBuffer& operator=(const MoveableBuffer&);
- ~MoveableBuffer();
-
- void *p;
- };
-
- /* implementation (inlines) below */
-
- // this is a temp stub implementation...not really done yet - just having everything compile & such for checkpointing into git
-
- inline MoveableBuffer::MoveableBuffer() : p(0) { }
-
- inline MoveableBuffer::MoveableBuffer(void *_p) : p(_p) { }
-
- inline MoveableBuffer& MoveableBuffer::operator=(const MoveableBuffer& r) {
- p = r.p;
- return *this;
- }
-
- inline MoveableBuffer::~MoveableBuffer() {
- }
-
-}
diff --git a/util/net/hostandport.h b/util/net/hostandport.h
deleted file mode 100644
index 573e8eef1fb..00000000000
--- a/util/net/hostandport.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// hostandport.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "sock.h"
-#include "../../db/cmdline.h"
-#include "../mongoutils/str.h"
-
-namespace mongo {
-
- using namespace mongoutils;
-
- /** helper for manipulating host:port connection endpoints.
- */
- struct HostAndPort {
- HostAndPort() : _port(-1) { }
-
- /** From a string hostname[:portnumber]
- Throws user assertion if bad config string or bad port #.
- */
- HostAndPort(string s);
-
- /** @param p port number. -1 is ok to use default. */
- HostAndPort(string h, int p /*= -1*/) : _host(h), _port(p) { }
-
- HostAndPort(const SockAddr& sock )
- : _host( sock.getAddr() ) , _port( sock.getPort() ) {
- }
-
- static HostAndPort me() {
- return HostAndPort("localhost", cmdLine.port);
- }
-
- /* uses real hostname instead of localhost */
- static HostAndPort Me();
-
- bool operator<(const HostAndPort& r) const {
- if( _host < r._host )
- return true;
- if( _host == r._host )
- return port() < r.port();
- return false;
- }
-
- bool operator==(const HostAndPort& r) const {
- return _host == r._host && port() == r.port();
- }
-
- bool operator!=(const HostAndPort& r) const {
- return _host != r._host || port() != r.port();
- }
-
- /* returns true if the host/port combo identifies this process instance. */
- bool isSelf() const; // defined in message.cpp
-
- bool isLocalHost() const;
-
- /**
- * @param includePort host:port if true, host otherwise
- */
- string toString( bool includePort=true ) const;
-
- operator string() const { return toString(); }
-
- string host() const { return _host; }
-
- int port() const { return _port >= 0 ? _port : CmdLine::DefaultDBPort; }
- bool hasPort() const { return _port >= 0; }
- void setPort( int port ) { _port = port; }
-
- private:
- // invariant (except full obj assignment):
- string _host;
- int _port; // -1 indicates unspecified
- };
-
- inline HostAndPort HostAndPort::Me() {
- const char* ips = cmdLine.bind_ip.c_str();
- while(*ips) {
- string ip;
- const char * comma = strchr(ips, ',');
- if (comma) {
- ip = string(ips, comma - ips);
- ips = comma + 1;
- }
- else {
- ip = string(ips);
- ips = "";
- }
- HostAndPort h = HostAndPort(ip, cmdLine.port);
- if (!h.isLocalHost()) {
- return h;
- }
- }
-
- string h = getHostName();
- assert( !h.empty() );
- assert( h != "localhost" );
- return HostAndPort(h, cmdLine.port);
- }
-
- inline string HostAndPort::toString( bool includePort ) const {
- if ( ! includePort )
- return _host;
-
- stringstream ss;
- ss << _host;
- if ( _port != -1 ) {
- ss << ':';
-#if defined(_DEBUG)
- if( _port >= 44000 && _port < 44100 ) {
- log() << "warning: special debug port 44xxx used" << endl;
- ss << _port+1;
- }
- else
- ss << _port;
-#else
- ss << _port;
-#endif
- }
- return ss.str();
- }
-
- inline bool HostAndPort::isLocalHost() const {
- return ( _host == "localhost"
- || startsWith(_host.c_str(), "127.")
- || _host == "::1"
- || _host == "anonymous unix socket"
- || _host.c_str()[0] == '/' // unix socket
- );
- }
-
- inline HostAndPort::HostAndPort(string s) {
- const char *p = s.c_str();
- uassert(13110, "HostAndPort: bad config string", *p);
- const char *colon = strrchr(p, ':');
- if( colon ) {
- int port = atoi(colon+1);
- uassert(13095, "HostAndPort: bad port #", port > 0);
- _host = string(p,colon-p);
- _port = port;
- }
- else {
- // no port specified.
- _host = p;
- _port = -1;
- }
- }
-
-}
diff --git a/util/net/httpclient.cpp b/util/net/httpclient.cpp
deleted file mode 100644
index 16eaa0ae80a..00000000000
--- a/util/net/httpclient.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-// httpclient.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "httpclient.h"
-#include "sock.h"
-#include "message.h"
-#include "message_port.h"
-#include "../mongoutils/str.h"
-#include "../../bson/util/builder.h"
-
-namespace mongo {
-
- //#define HD(x) cout << x << endl;
-#define HD(x)
-
-
- int HttpClient::get( string url , Result * result ) {
- return _go( "GET" , url , 0 , result );
- }
-
- int HttpClient::post( string url , string data , Result * result ) {
- return _go( "POST" , url , data.c_str() , result );
- }
-
- int HttpClient::_go( const char * command , string url , const char * body , Result * result ) {
- bool ssl = false;
- if ( url.find( "https://" ) == 0 ) {
- ssl = true;
- url = url.substr( 8 );
- }
- else {
- uassert( 10271 , "invalid url" , url.find( "http://" ) == 0 );
- url = url.substr( 7 );
- }
-
- string host , path;
- if ( url.find( "/" ) == string::npos ) {
- host = url;
- path = "/";
- }
- else {
- host = url.substr( 0 , url.find( "/" ) );
- path = url.substr( url.find( "/" ) );
- }
-
-
- HD( "host [" << host << "]" );
- HD( "path [" << path << "]" );
-
- string server = host;
- int port = ssl ? 443 : 80;
-
- string::size_type idx = host.find( ":" );
- if ( idx != string::npos ) {
- server = host.substr( 0 , idx );
- string t = host.substr( idx + 1 );
- port = atoi( t.c_str() );
- }
-
- HD( "server [" << server << "]" );
- HD( "port [" << port << "]" );
-
- string req;
- {
- stringstream ss;
- ss << command << " " << path << " HTTP/1.1\r\n";
- ss << "Host: " << host << "\r\n";
- ss << "Connection: Close\r\n";
- ss << "User-Agent: mongodb http client\r\n";
- if ( body ) {
- ss << "Content-Length: " << strlen( body ) << "\r\n";
- }
- ss << "\r\n";
- if ( body ) {
- ss << body;
- }
-
- req = ss.str();
- }
-
- SockAddr addr( server.c_str() , port );
- HD( "addr: " << addr.toString() );
-
- Socket sock;
- if ( ! sock.connect( addr ) )
- return -1;
-
- if ( ssl ) {
-#ifdef MONGO_SSL
- _checkSSLManager();
- sock.secure( _sslManager.get() );
-#else
- uasserted( 15862 , "no ssl support" );
-#endif
- }
-
- {
- const char * out = req.c_str();
- int toSend = req.size();
- sock.send( out , toSend, "_go" );
- }
-
- char buf[4096];
- int got = sock.unsafe_recv( buf , 4096 );
- buf[got] = 0;
-
- int rc;
- char version[32];
- assert( sscanf( buf , "%s %d" , version , &rc ) == 2 );
- HD( "rc: " << rc );
-
- StringBuilder sb;
- if ( result )
- sb << buf;
-
- while ( ( got = sock.unsafe_recv( buf , 4096 ) ) > 0) {
- if ( result )
- sb << buf;
- }
-
- if ( result ) {
- result->_init( rc , sb.str() );
- }
-
- return rc;
- }
-
- void HttpClient::Result::_init( int code , string entire ) {
- _code = code;
- _entireResponse = entire;
-
- while ( true ) {
- size_t i = entire.find( '\n' );
- if ( i == string::npos ) {
- // invalid
- break;
- }
-
- string h = entire.substr( 0 , i );
- entire = entire.substr( i + 1 );
-
- if ( h.size() && h[h.size()-1] == '\r' )
- h = h.substr( 0 , h.size() - 1 );
-
- if ( h.size() == 0 )
- break;
-
- i = h.find( ':' );
- if ( i != string::npos )
- _headers[h.substr(0,i)] = str::ltrim(h.substr(i+1));
- }
-
- _body = entire;
- }
-
-#ifdef MONGO_SSL
- void HttpClient::_checkSSLManager() {
- _sslManager.reset( new SSLManager( true ) );
- }
-#endif
-
-}
diff --git a/util/net/httpclient.h b/util/net/httpclient.h
deleted file mode 100644
index 126969f4f70..00000000000
--- a/util/net/httpclient.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// httpclient.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../../pch.h"
-#include "sock.h"
-
-namespace mongo {
-
- class HttpClient : boost::noncopyable {
- public:
-
- typedef map<string,string> Headers;
-
- class Result {
- public:
- Result() {}
-
- const string& getEntireResponse() const {
- return _entireResponse;
- }
-
- Headers getHeaders() const {
- return _headers;
- }
-
- const string& getBody() const {
- return _body;
- }
-
- private:
-
- void _init( int code , string entire );
-
- int _code;
- string _entireResponse;
-
- Headers _headers;
- string _body;
-
- friend class HttpClient;
- };
-
- /**
- * @return response code
- */
- int get( string url , Result * result = 0 );
-
- /**
- * @return response code
- */
- int post( string url , string body , Result * result = 0 );
-
- private:
- int _go( const char * command , string url , const char * body , Result * result );
-
-#ifdef MONGO_SSL
- void _checkSSLManager();
-
- scoped_ptr<SSLManager> _sslManager;
-#endif
- };
-}
diff --git a/util/net/listen.cpp b/util/net/listen.cpp
deleted file mode 100644
index 6ee25b4583f..00000000000
--- a/util/net/listen.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-// listen.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "pch.h"
-#include "listen.h"
-#include "message_port.h"
-
-#ifndef _WIN32
-
-# ifndef __sunos__
-# include <ifaddrs.h>
-# endif
-# include <sys/resource.h>
-# include <sys/stat.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netdb.h>
-#ifdef __openbsd__
-# include <sys/uio.h>
-#endif
-
-#else
-
-// errno doesn't work for winsock.
-#undef errno
-#define errno WSAGetLastError()
-
-#endif
-
-namespace mongo {
-
-
- void checkTicketNumbers();
-
-
- // ----- Listener -------
-
- const Listener* Listener::_timeTracker;
-
- vector<SockAddr> ipToAddrs(const char* ips, int port, bool useUnixSockets) {
- vector<SockAddr> out;
- if (*ips == '\0') {
- out.push_back(SockAddr("0.0.0.0", port)); // IPv4 all
-
- if (IPv6Enabled())
- out.push_back(SockAddr("::", port)); // IPv6 all
-#ifndef _WIN32
- if (useUnixSockets)
- out.push_back(SockAddr(makeUnixSockPath(port).c_str(), port)); // Unix socket
-#endif
- return out;
- }
-
- while(*ips) {
- string ip;
- const char * comma = strchr(ips, ',');
- if (comma) {
- ip = string(ips, comma - ips);
- ips = comma + 1;
- }
- else {
- ip = string(ips);
- ips = "";
- }
-
- SockAddr sa(ip.c_str(), port);
- out.push_back(sa);
-
-#ifndef _WIN32
- if (useUnixSockets && (sa.getAddr() == "127.0.0.1" || sa.getAddr() == "0.0.0.0")) // only IPv4
- out.push_back(SockAddr(makeUnixSockPath(port).c_str(), port));
-#endif
- }
- return out;
-
- }
-
- Listener::Listener(const string& name, const string &ip, int port, bool logConnect )
- : _port(port), _name(name), _ip(ip), _logConnect(logConnect), _elapsedTime(0) {
-#ifdef MONGO_SSL
- _ssl = 0;
- _sslPort = 0;
-
- if ( cmdLine.sslOnNormalPorts && cmdLine.sslServerManager ) {
- secure( cmdLine.sslServerManager );
- }
-#endif
- }
-
- Listener::~Listener() {
- if ( _timeTracker == this )
- _timeTracker = 0;
- }
-
-#ifdef MONGO_SSL
- void Listener::secure( SSLManager* manager ) {
- _ssl = manager;
- }
-
- void Listener::addSecurePort( SSLManager* manager , int additionalPort ) {
- _ssl = manager;
- _sslPort = additionalPort;
- }
-
-#endif
-
- bool Listener::_setupSockets( const vector<SockAddr>& mine , vector<int>& socks ) {
- for (vector<SockAddr>::const_iterator it=mine.begin(), end=mine.end(); it != end; ++it) {
- const SockAddr& me = *it;
-
- SOCKET sock = ::socket(me.getType(), SOCK_STREAM, 0);
- massert( 15863 , str::stream() << "listen(): invalid socket? " << errnoWithDescription() , sock >= 0 );
-
- if (me.getType() == AF_UNIX) {
-#if !defined(_WIN32)
- if (unlink(me.getAddr().c_str()) == -1) {
- int x = errno;
- if (x != ENOENT) {
- log() << "couldn't unlink socket file " << me << errnoWithDescription(x) << " skipping" << endl;
- continue;
- }
- }
-#endif
- }
- else if (me.getType() == AF_INET6) {
- // IPv6 can also accept IPv4 connections as mapped addresses (::ffff:127.0.0.1)
- // That causes a conflict if we don't do set it to IPV6_ONLY
- const int one = 1;
- setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &one, sizeof(one));
- }
-
-#if !defined(_WIN32)
- {
- const int one = 1;
- if ( setsockopt( sock , SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0 )
- out() << "Failed to set socket opt, SO_REUSEADDR" << endl;
- }
-#endif
-
- if ( ::bind(sock, me.raw(), me.addressSize) != 0 ) {
- int x = errno;
- error() << "listen(): bind() failed " << errnoWithDescription(x) << " for socket: " << me.toString() << endl;
- if ( x == EADDRINUSE )
- error() << " addr already in use" << endl;
- closesocket(sock);
- return false;
- }
-
-#if !defined(_WIN32)
- if (me.getType() == AF_UNIX) {
- if (chmod(me.getAddr().c_str(), 0777) == -1) {
- error() << "couldn't chmod socket file " << me << errnoWithDescription() << endl;
- }
- ListeningSockets::get()->addPath( me.getAddr() );
- }
-#endif
-
- if ( ::listen(sock, 128) != 0 ) {
- error() << "listen(): listen() failed " << errnoWithDescription() << endl;
- closesocket(sock);
- return false;
- }
-
- ListeningSockets::get()->add( sock );
-
- socks.push_back(sock);
- }
-
- return true;
- }
-
- void Listener::initAndListen() {
- checkTicketNumbers();
- vector<int> socks;
- set<int> sslSocks;
-
- { // normal sockets
- vector<SockAddr> mine = ipToAddrs(_ip.c_str(), _port, (!cmdLine.noUnixSocket && useUnixSockets()));
- if ( ! _setupSockets( mine , socks ) )
- return;
- }
-
-#ifdef MONGO_SSL
- if ( _ssl && _sslPort > 0 ) {
- unsigned prev = socks.size();
-
- vector<SockAddr> mine = ipToAddrs(_ip.c_str(), _sslPort, false );
- if ( ! _setupSockets( mine , socks ) )
- return;
-
- for ( unsigned i=prev; i<socks.size(); i++ ) {
- sslSocks.insert( socks[i] );
- }
-
- }
-#endif
-
- SOCKET maxfd = 0; // needed for select()
- for ( unsigned i=0; i<socks.size(); i++ ) {
- if ( socks[i] > maxfd )
- maxfd = socks[i];
- }
-
-#ifdef MONGO_SSL
- if ( _ssl == 0 ) {
- _logListen( _port , false );
- }
- else if ( _sslPort == 0 ) {
- _logListen( _port , true );
- }
- else {
- // both
- _logListen( _port , false );
- _logListen( _sslPort , true );
- }
-#else
- _logListen( _port , false );
-#endif
-
- static long connNumber = 0;
- struct timeval maxSelectTime;
- while ( ! inShutdown() ) {
- fd_set fds[1];
- FD_ZERO(fds);
-
- for (vector<int>::iterator it=socks.begin(), end=socks.end(); it != end; ++it) {
- FD_SET(*it, fds);
- }
-
- maxSelectTime.tv_sec = 0;
- maxSelectTime.tv_usec = 10000;
- const int ret = select(maxfd+1, fds, NULL, NULL, &maxSelectTime);
-
- if (ret == 0) {
-#if defined(__linux__)
- _elapsedTime += ( 10000 - maxSelectTime.tv_usec ) / 1000;
-#else
- _elapsedTime += 10;
-#endif
- continue;
- }
-
- if (ret < 0) {
- int x = errno;
-#ifdef EINTR
- if ( x == EINTR ) {
- log() << "select() signal caught, continuing" << endl;
- continue;
- }
-#endif
- if ( ! inShutdown() )
- log() << "select() failure: ret=" << ret << " " << errnoWithDescription(x) << endl;
- return;
- }
-
-#if defined(__linux__)
- _elapsedTime += max(ret, (int)(( 10000 - maxSelectTime.tv_usec ) / 1000));
-#else
- _elapsedTime += ret; // assume 1ms to grab connection. very rough
-#endif
-
- for (vector<int>::iterator it=socks.begin(), end=socks.end(); it != end; ++it) {
- if (! (FD_ISSET(*it, fds)))
- continue;
-
- SockAddr from;
- int s = accept(*it, from.raw(), &from.addressSize);
- if ( s < 0 ) {
- int x = errno; // so no global issues
- if ( x == ECONNABORTED || x == EBADF ) {
- log() << "Listener on port " << _port << " aborted" << endl;
- return;
- }
- if ( x == 0 && inShutdown() ) {
- return; // socket closed
- }
- if( !inShutdown() ) {
- log() << "Listener: accept() returns " << s << " " << errnoWithDescription(x) << endl;
- if (x == EMFILE || x == ENFILE) {
- // Connection still in listen queue but we can't accept it yet
- error() << "Out of file descriptors. Waiting one second before trying to accept more connections." << warnings;
- sleepsecs(1);
- }
- }
- continue;
- }
- if (from.getType() != AF_UNIX)
- disableNagle(s);
- if ( _logConnect && ! cmdLine.quiet )
- log() << "connection accepted from " << from.toString() << " #" << ++connNumber << endl;
-
- Socket newSock = Socket(s, from);
-#ifdef MONGO_SSL
- if ( _ssl && ( _sslPort == 0 || sslSocks.count(*it) ) ) {
- newSock.secureAccepted( _ssl );
- }
-#endif
- accepted( newSock );
- }
- }
- }
-
- void Listener::_logListen( int port , bool ssl ) {
- log() << _name << ( _name.size() ? " " : "" ) << "waiting for connections on port " << port << ( ssl ? " ssl" : "" ) << endl;
- }
-
-
- void Listener::accepted(Socket socket) {
- accepted( new MessagingPort(socket) );
- }
-
- void Listener::accepted(MessagingPort *mp) {
- assert(!"You must overwrite one of the accepted methods");
- }
-
- // ----- ListeningSockets -------
-
- ListeningSockets* ListeningSockets::_instance = new ListeningSockets();
-
- ListeningSockets* ListeningSockets::get() {
- return _instance;
- }
-
- // ------ connection ticket and control ------
-
- const int DEFAULT_MAX_CONN = 20000;
- const int MAX_MAX_CONN = 20000;
-
- int getMaxConnections() {
-#ifdef _WIN32
- return DEFAULT_MAX_CONN;
-#else
- struct rlimit limit;
- assert( getrlimit(RLIMIT_NOFILE,&limit) == 0 );
-
- int max = (int)(limit.rlim_cur * .8);
-
- log(1) << "fd limit"
- << " hard:" << limit.rlim_max
- << " soft:" << limit.rlim_cur
- << " max conn: " << max
- << endl;
-
- if ( max > MAX_MAX_CONN )
- max = MAX_MAX_CONN;
-
- return max;
-#endif
- }
-
- void checkTicketNumbers() {
- int want = getMaxConnections();
- int current = connTicketHolder.outof();
- if ( current != DEFAULT_MAX_CONN ) {
- if ( current < want ) {
- // they want fewer than they can handle
- // which is fine
- log(1) << " only allowing " << current << " connections" << endl;
- return;
- }
- if ( current > want ) {
- log() << " --maxConns too high, can only handle " << want << endl;
- }
- }
- connTicketHolder.resize( want );
- }
-
- TicketHolder connTicketHolder(DEFAULT_MAX_CONN);
-
-}
diff --git a/util/net/listen.h b/util/net/listen.h
deleted file mode 100644
index a2289bc219f..00000000000
--- a/util/net/listen.h
+++ /dev/null
@@ -1,194 +0,0 @@
-// listen.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "sock.h"
-
-namespace mongo {
-
- class MessagingPort;
-
- class Listener : boost::noncopyable {
- public:
-
- Listener(const string& name, const string &ip, int port, bool logConnect=true );
-
- virtual ~Listener();
-
-#ifdef MONGO_SSL
- /**
- * make this an ssl socket
- * ownership of SSLManager remains with the caller
- */
- void secure( SSLManager* manager );
-
- void addSecurePort( SSLManager* manager , int additionalPort );
-#endif
-
- void initAndListen(); // never returns unless error (start a thread)
-
- /* spawn a thread, etc., then return */
- virtual void accepted(Socket socket);
- virtual void accepted(MessagingPort *mp);
-
- const int _port;
-
- /**
- * @return a rough estimate of elapsed time since the server started
- */
- long long getMyElapsedTimeMillis() const { return _elapsedTime; }
-
- void setAsTimeTracker() {
- _timeTracker = this;
- }
-
- static const Listener* getTimeTracker() {
- return _timeTracker;
- }
-
- static long long getElapsedTimeMillis() {
- if ( _timeTracker )
- return _timeTracker->getMyElapsedTimeMillis();
-
- // should this assert or throw? seems like callers may not expect to get zero back, certainly not forever.
- return 0;
- }
-
- private:
- string _name;
- string _ip;
- bool _logConnect;
- long long _elapsedTime;
-
-#ifdef MONGO_SSL
- SSLManager* _ssl;
- int _sslPort;
-#endif
-
- /**
- * @return true iff everything went ok
- */
- bool _setupSockets( const vector<SockAddr>& mine , vector<int>& socks );
-
- void _logListen( int port , bool ssl );
-
- static const Listener* _timeTracker;
-
- virtual bool useUnixSockets() const { return false; }
- };
-
- /**
- * keep track of elapsed time
- * after a set amount of time, tells you to do something
- * only in this file because depends on Listener
- */
- class ElapsedTracker {
- public:
- ElapsedTracker( int hitsBetweenMarks , int msBetweenMarks )
- : _h( hitsBetweenMarks ) , _ms( msBetweenMarks ) , _pings(0) {
- _last = Listener::getElapsedTimeMillis();
- }
-
- /**
- * call this for every iteration
- * returns true if one of the triggers has gone off
- */
- bool ping() {
- if ( ( ++_pings % _h ) == 0 ) {
- _last = Listener::getElapsedTimeMillis();
- return true;
- }
-
- long long now = Listener::getElapsedTimeMillis();
- if ( now - _last > _ms ) {
- _last = now;
- return true;
- }
-
- return false;
- }
-
- void resetLastTime() {
- _last = Listener::getElapsedTimeMillis();
- }
-
- private:
- int _h;
- int _ms;
-
- unsigned long long _pings;
-
- long long _last;
-
- };
-
- class ListeningSockets {
- public:
- ListeningSockets()
- : _mutex("ListeningSockets")
- , _sockets( new set<int>() )
- , _socketPaths( new set<string>() )
- { }
- void add( int sock ) {
- scoped_lock lk( _mutex );
- _sockets->insert( sock );
- }
- void addPath( string path ) {
- scoped_lock lk( _mutex );
- _socketPaths->insert( path );
- }
- void remove( int sock ) {
- scoped_lock lk( _mutex );
- _sockets->erase( sock );
- }
- void closeAll() {
- set<int>* sockets;
- set<string>* paths;
-
- {
- scoped_lock lk( _mutex );
- sockets = _sockets;
- _sockets = new set<int>();
- paths = _socketPaths;
- _socketPaths = new set<string>();
- }
-
- for ( set<int>::iterator i=sockets->begin(); i!=sockets->end(); i++ ) {
- int sock = *i;
- log() << "closing listening socket: " << sock << endl;
- closesocket( sock );
- }
-
- for ( set<string>::iterator i=paths->begin(); i!=paths->end(); i++ ) {
- string path = *i;
- log() << "removing socket file: " << path << endl;
- ::remove( path.c_str() );
- }
- }
- static ListeningSockets* get();
- private:
- mongo::mutex _mutex;
- set<int>* _sockets;
- set<string>* _socketPaths; // for unix domain sockets
- static ListeningSockets* _instance;
- };
-
-
- extern TicketHolder connTicketHolder;
-
-}
diff --git a/util/net/message.cpp b/util/net/message.cpp
deleted file mode 100644
index a84e5c48c5c..00000000000
--- a/util/net/message.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-// message.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-
-#include "message.h"
-#include "message_port.h"
-#include "listen.h"
-
-#include "../goodies.h"
-#include "../../client/dbclient.h"
-
-namespace mongo {
-
- void Message::send( MessagingPort &p, const char *context ) {
- if ( empty() ) {
- return;
- }
- if ( _buf != 0 ) {
- p.send( (char*)_buf, _buf->len, context );
- }
- else {
- p.send( _data, context );
- }
- }
-
- MSGID NextMsgId;
-
- /*struct MsgStart {
- MsgStart() {
- NextMsgId = (((unsigned) time(0)) << 16) ^ curTimeMillis();
- assert(MsgDataHeaderSize == 16);
- }
- } msgstart;*/
-
- MSGID nextMessageId() {
- MSGID msgid = NextMsgId++;
- return msgid;
- }
-
- bool doesOpGetAResponse( int op ) {
- return op == dbQuery || op == dbGetMore;
- }
-
-
-} // namespace mongo
diff --git a/util/net/message.h b/util/net/message.h
deleted file mode 100644
index 16da5d64e7e..00000000000
--- a/util/net/message.h
+++ /dev/null
@@ -1,312 +0,0 @@
-// message.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "sock.h"
-#include "../../bson/util/atomic_int.h"
-#include "hostandport.h"
-
-namespace mongo {
-
- class Message;
- class MessagingPort;
- class PiggyBackData;
-
- typedef AtomicUInt MSGID;
-
- enum Operations {
- opReply = 1, /* reply. responseTo is set. */
- dbMsg = 1000, /* generic msg command followed by a string */
- dbUpdate = 2001, /* update object */
- dbInsert = 2002,
- //dbGetByOID = 2003,
- dbQuery = 2004,
- dbGetMore = 2005,
- dbDelete = 2006,
- dbKillCursors = 2007
- };
-
- bool doesOpGetAResponse( int op );
-
- inline const char * opToString( int op ) {
- switch ( op ) {
- case 0: return "none";
- case opReply: return "reply";
- case dbMsg: return "msg";
- case dbUpdate: return "update";
- case dbInsert: return "insert";
- case dbQuery: return "query";
- case dbGetMore: return "getmore";
- case dbDelete: return "remove";
- case dbKillCursors: return "killcursors";
- default:
- PRINT(op);
- assert(0);
- return "";
- }
- }
-
- inline bool opIsWrite( int op ) {
- switch ( op ) {
-
- case 0:
- case opReply:
- case dbMsg:
- case dbQuery:
- case dbGetMore:
- case dbKillCursors:
- return false;
-
- case dbUpdate:
- case dbInsert:
- case dbDelete:
- return false;
-
- default:
- PRINT(op);
- assert(0);
- return "";
- }
-
- }
-
-#pragma pack(1)
- /* see http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol
- */
- struct MSGHEADER {
- int messageLength; // total message size, including this
- int requestID; // identifier for this message
- int responseTo; // requestID from the original request
- // (used in reponses from db)
- int opCode;
- };
- struct OP_GETMORE : public MSGHEADER {
- MSGHEADER header; // standard message header
- int ZERO_or_flags; // 0 - reserved for future use
- //cstring fullCollectionName; // "dbname.collectionname"
- //int32 numberToReturn; // number of documents to return
- //int64 cursorID; // cursorID from the OP_REPLY
- };
-#pragma pack()
-
-#pragma pack(1)
- /* todo merge this with MSGHEADER (or inherit from it). */
- struct MsgData {
- int len; /* len of the msg, including this field */
- MSGID id; /* request/reply id's match... */
- MSGID responseTo; /* id of the message we are responding to */
- short _operation;
- char _flags;
- char _version;
- int operation() const {
- return _operation;
- }
- void setOperation(int o) {
- _flags = 0;
- _version = 0;
- _operation = o;
- }
- char _data[4];
-
- int& dataAsInt() {
- return *((int *) _data);
- }
-
- bool valid() {
- if ( len <= 0 || len > ( 4 * BSONObjMaxInternalSize ) )
- return false;
- if ( _operation < 0 || _operation > 30000 )
- return false;
- return true;
- }
-
- long long getCursor() {
- assert( responseTo > 0 );
- assert( _operation == opReply );
- long long * l = (long long *)(_data + 4);
- return l[0];
- }
-
- int dataLen(); // len without header
- };
- const int MsgDataHeaderSize = sizeof(MsgData) - 4;
- inline int MsgData::dataLen() {
- return len - MsgDataHeaderSize;
- }
-#pragma pack()
-
- class Message {
- public:
- // we assume here that a vector with initial size 0 does no allocation (0 is the default, but wanted to make it explicit).
- Message() : _buf( 0 ), _data( 0 ), _freeIt( false ) {}
- Message( void * data , bool freeIt ) :
- _buf( 0 ), _data( 0 ), _freeIt( false ) {
- _setData( reinterpret_cast< MsgData* >( data ), freeIt );
- };
- Message(Message& r) : _buf( 0 ), _data( 0 ), _freeIt( false ) {
- *this = r;
- }
- ~Message() {
- reset();
- }
-
- SockAddr _from;
-
- MsgData *header() const {
- assert( !empty() );
- return _buf ? _buf : reinterpret_cast< MsgData* > ( _data[ 0 ].first );
- }
- int operation() const { return header()->operation(); }
-
- MsgData *singleData() const {
- massert( 13273, "single data buffer expected", _buf );
- return header();
- }
-
- bool empty() const { return !_buf && _data.empty(); }
-
- int size() const {
- int res = 0;
- if ( _buf ) {
- res = _buf->len;
- }
- else {
- for (MsgVec::const_iterator it = _data.begin(); it != _data.end(); ++it) {
- res += it->second;
- }
- }
- return res;
- }
-
- int dataSize() const { return size() - sizeof(MSGHEADER); }
-
- // concat multiple buffers - noop if <2 buffers already, otherwise can be expensive copy
- // can get rid of this if we make response handling smarter
- void concat() {
- if ( _buf || empty() ) {
- return;
- }
-
- assert( _freeIt );
- int totalSize = 0;
- for( vector< pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i ) {
- totalSize += i->second;
- }
- char *buf = (char*)malloc( totalSize );
- char *p = buf;
- for( vector< pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i ) {
- memcpy( p, i->first, i->second );
- p += i->second;
- }
- reset();
- _setData( (MsgData*)buf, true );
- }
-
- // vector swap() so this is fast
- Message& operator=(Message& r) {
- assert( empty() );
- assert( r._freeIt );
- _buf = r._buf;
- r._buf = 0;
- if ( r._data.size() > 0 ) {
- _data.swap( r._data );
- }
- r._freeIt = false;
- _freeIt = true;
- return *this;
- }
-
- void reset() {
- if ( _freeIt ) {
- if ( _buf ) {
- free( _buf );
- }
- for( vector< pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i ) {
- free(i->first);
- }
- }
- _buf = 0;
- _data.clear();
- _freeIt = false;
- }
-
- // use to add a buffer
- // assumes message will free everything
- void appendData(char *d, int size) {
- if ( size <= 0 ) {
- return;
- }
- if ( empty() ) {
- MsgData *md = (MsgData*)d;
- md->len = size; // can be updated later if more buffers added
- _setData( md, true );
- return;
- }
- assert( _freeIt );
- if ( _buf ) {
- _data.push_back( make_pair( (char*)_buf, _buf->len ) );
- _buf = 0;
- }
- _data.push_back( make_pair( d, size ) );
- header()->len += size;
- }
-
- // use to set first buffer if empty
- void setData(MsgData *d, bool freeIt) {
- assert( empty() );
- _setData( d, freeIt );
- }
- void setData(int operation, const char *msgtxt) {
- setData(operation, msgtxt, strlen(msgtxt)+1);
- }
- void setData(int operation, const char *msgdata, size_t len) {
- assert( empty() );
- size_t dataLen = len + sizeof(MsgData) - 4;
- MsgData *d = (MsgData *) malloc(dataLen);
- memcpy(d->_data, msgdata, len);
- d->len = fixEndian(dataLen);
- d->setOperation(operation);
- _setData( d, true );
- }
-
- bool doIFreeIt() {
- return _freeIt;
- }
-
- void send( MessagingPort &p, const char *context );
-
- string toString() const;
-
- private:
- void _setData( MsgData *d, bool freeIt ) {
- _freeIt = freeIt;
- _buf = d;
- }
- // if just one buffer, keep it in _buf, otherwise keep a sequence of buffers in _data
- MsgData * _buf;
- // byte buffer(s) - the first must contain at least a full MsgData unless using _buf for storage instead
- typedef vector< pair< char*, int > > MsgVec;
- MsgVec _data;
- bool _freeIt;
- };
-
-
- MSGID nextMessageId();
-
-
-} // namespace mongo
diff --git a/util/net/message_port.cpp b/util/net/message_port.cpp
deleted file mode 100644
index 29764c3ecdc..00000000000
--- a/util/net/message_port.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-// message_port.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-
-#include "message.h"
-#include "message_port.h"
-#include "listen.h"
-
-#include "../goodies.h"
-#include "../background.h"
-#include "../time_support.h"
-#include "../../db/cmdline.h"
-#include "../../client/dbclient.h"
-
-
-#ifndef _WIN32
-# ifndef __sunos__
-# include <ifaddrs.h>
-# endif
-# include <sys/resource.h>
-# include <sys/stat.h>
-#else
-
-// errno doesn't work for winsock.
-#undef errno
-#define errno WSAGetLastError()
-
-#endif
-
-namespace mongo {
-
-
-// if you want trace output:
-#define mmm(x)
-
- /* messagingport -------------------------------------------------------------- */
-
- class PiggyBackData {
- public:
- PiggyBackData( MessagingPort * port ) {
- _port = port;
- _buf = new char[1300];
- _cur = _buf;
- }
-
- ~PiggyBackData() {
- DESTRUCTOR_GUARD (
- flush();
- delete[]( _cur );
- );
- }
-
- void append( Message& m ) {
- assert( m.header()->len <= 1300 );
-
- if ( len() + m.header()->len > 1300 )
- flush();
-
- memcpy( _cur , m.singleData() , m.header()->len );
- _cur += m.header()->len;
- }
-
- void flush() {
- if ( _buf == _cur )
- return;
-
- _port->send( _buf , len(), "flush" );
- _cur = _buf;
- }
-
- int len() const { return _cur - _buf; }
-
- private:
- MessagingPort* _port;
- char * _buf;
- char * _cur;
- };
-
- class Ports {
- set<MessagingPort*> ports;
- mongo::mutex m;
- public:
- Ports() : ports(), m("Ports") {}
- void closeAll(unsigned skip_mask) {
- scoped_lock bl(m);
- for ( set<MessagingPort*>::iterator i = ports.begin(); i != ports.end(); i++ ) {
- if( (*i)->tag & skip_mask )
- continue;
- (*i)->shutdown();
- }
- }
- void insert(MessagingPort* p) {
- scoped_lock bl(m);
- ports.insert(p);
- }
- void erase(MessagingPort* p) {
- scoped_lock bl(m);
- ports.erase(p);
- }
- };
-
- // we "new" this so it is still be around when other automatic global vars
- // are being destructed during termination.
- Ports& ports = *(new Ports());
-
- void MessagingPort::closeAllSockets(unsigned mask) {
- ports.closeAll(mask);
- }
-
- MessagingPort::MessagingPort(int fd, const SockAddr& remote)
- : Socket( fd , remote ) , piggyBackData(0) {
- ports.insert(this);
- }
-
- MessagingPort::MessagingPort( double timeout, int ll )
- : Socket( timeout, ll ) {
- ports.insert(this);
- piggyBackData = 0;
- }
-
- MessagingPort::MessagingPort( Socket& sock )
- : Socket( sock ) , piggyBackData( 0 ) {
- ports.insert(this);
- }
-
- void MessagingPort::shutdown() {
- close();
- }
-
- MessagingPort::~MessagingPort() {
- if ( piggyBackData )
- delete( piggyBackData );
- shutdown();
- ports.erase(this);
- }
-
- bool MessagingPort::recv(Message& m) {
- try {
-again:
- mmm( log() << "* recv() sock:" << this->sock << endl; )
- int len = -1;
-
- char *lenbuf = (char *) &len;
- int lft = 4;
- Socket::recv( lenbuf, lft );
-
- if ( len < 16 || len > 48000000 ) { // messages must be large enough for headers
- if ( len == -1 ) {
- // Endian check from the client, after connecting, to see what mode server is running in.
- unsigned foo = 0x10203040;
- send( (char *) &foo, 4, "endian" );
- goto again;
- }
-
- if ( len == 542393671 ) {
- // an http GET
- log(_logLevel) << "looks like you're trying to access db over http on native driver port. please add 1000 for webserver" << endl;
- string msg = "You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number\n";
- stringstream ss;
- ss << "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: " << msg.size() << "\r\n\r\n" << msg;
- string s = ss.str();
- send( s.c_str(), s.size(), "http" );
- return false;
- }
- log(0) << "recv(): message len " << len << " is too large" << len << endl;
- return false;
- }
-
- int z = (len+1023)&0xfffffc00;
- assert(z>=len);
- MsgData *md = (MsgData *) malloc(z);
- assert(md);
- md->len = len;
-
- char *p = (char *) &md->id;
- int left = len -4;
-
- try {
- Socket::recv( p, left );
- }
- catch (...) {
- free(md);
- throw;
- }
-
- m.setData(md, true);
- return true;
-
- }
- catch ( const SocketException & e ) {
- log(_logLevel + (e.shouldPrint() ? 0 : 1) ) << "SocketException: remote: " << remote() << " error: " << e << endl;
- m.reset();
- return false;
- }
- }
-
- void MessagingPort::reply(Message& received, Message& response) {
- say(/*received.from, */response, received.header()->id);
- }
-
- void MessagingPort::reply(Message& received, Message& response, MSGID responseTo) {
- say(/*received.from, */response, responseTo);
- }
-
- bool MessagingPort::call(Message& toSend, Message& response) {
- mmm( log() << "*call()" << endl; )
- say(toSend);
- return recv( toSend , response );
- }
-
- bool MessagingPort::recv( const Message& toSend , Message& response ) {
- while ( 1 ) {
- bool ok = recv(response);
- if ( !ok )
- return false;
- //log() << "got response: " << response.data->responseTo << endl;
- if ( response.header()->responseTo == toSend.header()->id )
- break;
- error() << "MessagingPort::call() wrong id got:" << hex << (unsigned)response.header()->responseTo << " expect:" << (unsigned)toSend.header()->id << '\n'
- << dec
- << " toSend op: " << (unsigned)toSend.operation() << '\n'
- << " response msgid:" << (unsigned)response.header()->id << '\n'
- << " response len: " << (unsigned)response.header()->len << '\n'
- << " response op: " << response.operation() << '\n'
- << " remote: " << remoteString() << endl;
- assert(false);
- response.reset();
- }
- mmm( log() << "*call() end" << endl; )
- return true;
- }
-
- void MessagingPort::say(Message& toSend, int responseTo) {
- assert( !toSend.empty() );
- mmm( log() << "* say() sock:" << this->sock << " thr:" << GetCurrentThreadId() << endl; )
- toSend.header()->id = nextMessageId();
- toSend.header()->responseTo = responseTo;
-
- if ( piggyBackData && piggyBackData->len() ) {
- mmm( log() << "* have piggy back" << endl; )
- if ( ( piggyBackData->len() + toSend.header()->len ) > 1300 ) {
- // won't fit in a packet - so just send it off
- piggyBackData->flush();
- }
- else {
- piggyBackData->append( toSend );
- piggyBackData->flush();
- return;
- }
- }
-
- toSend.send( *this, "say" );
- }
-
- void MessagingPort::piggyBack( Message& toSend , int responseTo ) {
-
- if ( toSend.header()->len > 1300 ) {
- // not worth saving because its almost an entire packet
- say( toSend );
- return;
- }
-
- // we're going to be storing this, so need to set it up
- toSend.header()->id = nextMessageId();
- toSend.header()->responseTo = responseTo;
-
- if ( ! piggyBackData )
- piggyBackData = new PiggyBackData( this );
-
- piggyBackData->append( toSend );
- }
-
- HostAndPort MessagingPort::remote() const {
- if ( ! _remoteParsed.hasPort() )
- _remoteParsed = HostAndPort( remoteAddr() );
- return _remoteParsed;
- }
-
-
-} // namespace mongo
diff --git a/util/net/message_port.h b/util/net/message_port.h
deleted file mode 100644
index 22ecafecfbc..00000000000
--- a/util/net/message_port.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// message_port.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "sock.h"
-#include "message.h"
-
-namespace mongo {
-
- class MessagingPort;
- class PiggyBackData;
-
- typedef AtomicUInt MSGID;
-
- class AbstractMessagingPort : boost::noncopyable {
- public:
- AbstractMessagingPort() : tag(0) {}
- virtual ~AbstractMessagingPort() { }
- virtual void reply(Message& received, Message& response, MSGID responseTo) = 0; // like the reply below, but doesn't rely on received.data still being available
- virtual void reply(Message& received, Message& response) = 0;
-
- virtual HostAndPort remote() const = 0;
- virtual unsigned remotePort() const = 0;
-
- private:
-
- public:
- // TODO make this private with some helpers
-
- /* ports can be tagged with various classes. see closeAllSockets(tag). defaults to 0. */
- unsigned tag;
-
- };
-
- class MessagingPort : public AbstractMessagingPort , public Socket {
- public:
- MessagingPort(int fd, const SockAddr& remote);
-
- // in some cases the timeout will actually be 2x this value - eg we do a partial send,
- // then the timeout fires, then we try to send again, then the timeout fires again with
- // no data sent, then we detect that the other side is down
- MessagingPort(double so_timeout = 0, int logLevel = 0 );
-
- MessagingPort(Socket& socket);
-
- virtual ~MessagingPort();
-
- void shutdown();
-
- /* it's assumed if you reuse a message object, that it doesn't cross MessagingPort's.
- also, the Message data will go out of scope on the subsequent recv call.
- */
- bool recv(Message& m);
- void reply(Message& received, Message& response, MSGID responseTo);
- void reply(Message& received, Message& response);
- bool call(Message& toSend, Message& response);
-
- void say(Message& toSend, int responseTo = -1);
-
- /**
- * this is used for doing 'async' queries
- * instead of doing call( to , from )
- * you would do
- * say( to )
- * recv( from )
- * Note: if you fail to call recv and someone else uses this port,
- * horrible things will happend
- */
- bool recv( const Message& sent , Message& response );
-
- void piggyBack( Message& toSend , int responseTo = -1 );
-
- unsigned remotePort() const { return Socket::remotePort(); }
- virtual HostAndPort remote() const;
-
-
- private:
-
- PiggyBackData * piggyBackData;
-
- // this is the parsed version of remote
- // mutable because its initialized only on call to remote()
- mutable HostAndPort _remoteParsed;
-
- public:
- static void closeAllSockets(unsigned tagMask = 0xffffffff);
-
- friend class PiggyBackData;
- };
-
-
-} // namespace mongo
diff --git a/util/net/message_server.h b/util/net/message_server.h
deleted file mode 100644
index ae77b97bb0f..00000000000
--- a/util/net/message_server.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// message_server.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- abstract database server
- async io core, worker thread system
- */
-
-#pragma once
-
-#include "../../pch.h"
-
-namespace mongo {
-
- class MessageHandler {
- public:
- virtual ~MessageHandler() {}
-
- /**
- * called once when a socket is connected
- */
- virtual void connected( AbstractMessagingPort* p ) = 0;
-
- /**
- * called every time a message comes in
- * handler is responsible for responding to client
- */
- virtual void process( Message& m , AbstractMessagingPort* p , LastError * err ) = 0;
-
- /**
- * called once when a socket is disconnected
- */
- virtual void disconnected( AbstractMessagingPort* p ) = 0;
- };
-
- class MessageServer {
- public:
- struct Options {
- int port; // port to bind to
- string ipList; // addresses to bind to
-
- Options() : port(0), ipList("") {}
- };
-
- virtual ~MessageServer() {}
- virtual void run() = 0;
- virtual void setAsTimeTracker() = 0;
- };
-
- // TODO use a factory here to decide between port and asio variations
- MessageServer * createServer( const MessageServer::Options& opts , MessageHandler * handler );
-}
diff --git a/util/net/message_server_asio.cpp b/util/net/message_server_asio.cpp
deleted file mode 100644
index 0c6a7d925da..00000000000
--- a/util/net/message_server_asio.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-// message_server_asio.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef USE_ASIO
-
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <iostream>
-#include <vector>
-
-#include "message.h"
-#include "message_server.h"
-#include "../util/concurrency/mvar.h"
-
-using namespace boost;
-using namespace boost::asio;
-using namespace boost::asio::ip;
-
-namespace mongo {
- class MessageServerSession;
-
- namespace {
- class StickyThread {
- public:
- StickyThread()
- : _thread(boost::ref(*this))
- {}
-
- ~StickyThread() {
- _mss.put(boost::shared_ptr<MessageServerSession>());
- _thread.join();
- }
-
- void ready(boost::shared_ptr<MessageServerSession> mss) {
- _mss.put(mss);
- }
-
- void operator() () {
- boost::shared_ptr<MessageServerSession> mss;
- while((mss = _mss.take())) { // intentionally not using ==
- task(mss.get());
- mss.reset();
- }
- }
-
- private:
- boost::thread _thread;
- inline void task(MessageServerSession* mss); // must be defined after MessageServerSession
-
- MVar<boost::shared_ptr<MessageServerSession> > _mss; // populated when given a task
- };
-
- vector<boost::shared_ptr<StickyThread> > thread_pool;
- mongo::mutex tp_mutex; // this is only needed if io_service::run() is called from multiple threads
- }
-
- class MessageServerSession : public boost::enable_shared_from_this<MessageServerSession> , public AbstractMessagingPort {
- public:
- MessageServerSession( MessageHandler * handler , io_service& ioservice )
- : _handler( handler )
- , _socket( ioservice )
- , _portCache(0)
- { }
-
- ~MessageServerSession() {
- cout << "disconnect from: " << _socket.remote_endpoint() << endl;
- }
-
- tcp::socket& socket() {
- return _socket;
- }
-
- void start() {
- cout << "MessageServerSession start from:" << _socket.remote_endpoint() << endl;
- _startHeaderRead();
- }
-
- void handleReadHeader( const boost::system::error_code& error ) {
- if ( _inHeader.len == 0 )
- return;
-
- if ( ! _inHeader.valid() ) {
- cout << " got invalid header from: " << _socket.remote_endpoint() << " closing connected" << endl;
- return;
- }
-
- char * raw = (char*)malloc( _inHeader.len );
-
- MsgData * data = (MsgData*)raw;
- memcpy( data , &_inHeader , sizeof( _inHeader ) );
- assert( data->len == _inHeader.len );
-
- uassert( 10273 , "_cur not empty! pipelining requests not supported" , ! _cur.data );
-
- _cur.setData( data , true );
- async_read( _socket ,
- buffer( raw + sizeof( _inHeader ) , _inHeader.len - sizeof( _inHeader ) ) ,
- boost::bind( &MessageServerSession::handleReadBody , shared_from_this() , boost::asio::placeholders::error ) );
- }
-
- void handleReadBody( const boost::system::error_code& error ) {
- if (!_myThread) {
- mongo::mutex::scoped_lock(tp_mutex);
- if (!thread_pool.empty()) {
- _myThread = thread_pool.back();
- thread_pool.pop_back();
- }
- }
-
- if (!_myThread) // pool is empty
- _myThread.reset(new StickyThread());
-
- assert(_myThread);
-
- _myThread->ready(shared_from_this());
- }
-
- void process() {
- _handler->process( _cur , this );
-
- if (_reply.data) {
- async_write( _socket ,
- buffer( (char*)_reply.data , _reply.data->len ) ,
- boost::bind( &MessageServerSession::handleWriteDone , shared_from_this() , boost::asio::placeholders::error ) );
- }
- else {
- _cur.reset();
- _startHeaderRead();
- }
- }
-
- void handleWriteDone( const boost::system::error_code& error ) {
- {
- // return thread to pool after we have sent data to the client
- mongo::mutex::scoped_lock(tp_mutex);
- assert(_myThread);
- thread_pool.push_back(_myThread);
- _myThread.reset();
- }
- _cur.reset();
- _reply.reset();
- _startHeaderRead();
- }
-
- virtual void reply( Message& received, Message& response ) {
- reply( received , response , received.data->id );
- }
-
- virtual void reply( Message& query , Message& toSend, MSGID responseTo ) {
- _reply = toSend;
-
- _reply.data->id = nextMessageId();
- _reply.data->responseTo = responseTo;
- uassert( 10274 , "pipelining requests doesn't work yet" , query.data->id == _cur.data->id );
- }
-
-
- virtual unsigned remotePort() {
- if (!_portCache)
- _portCache = _socket.remote_endpoint().port(); //this is expensive
- return _portCache;
- }
-
- private:
-
- void _startHeaderRead() {
- _inHeader.len = 0;
- async_read( _socket ,
- buffer( &_inHeader , sizeof( _inHeader ) ) ,
- boost::bind( &MessageServerSession::handleReadHeader , shared_from_this() , boost::asio::placeholders::error ) );
- }
-
- MessageHandler * _handler;
- tcp::socket _socket;
- MsgData _inHeader;
- Message _cur;
- Message _reply;
-
- unsigned _portCache;
-
- boost::shared_ptr<StickyThread> _myThread;
- };
-
- void StickyThread::task(MessageServerSession* mss) {
- mss->process();
- }
-
-
- class AsyncMessageServer : public MessageServer {
- public:
- // TODO accept an IP address to bind to
- AsyncMessageServer( const MessageServer::Options& opts , MessageHandler * handler )
- : _port( opts.port )
- , _handler(handler)
- , _endpoint( tcp::v4() , opts.port )
- , _acceptor( _ioservice , _endpoint ) {
- _accept();
- }
- virtual ~AsyncMessageServer() {
-
- }
-
- void run() {
- cout << "AsyncMessageServer starting to listen on: " << _port << endl;
- boost::thread other(boost::bind(&io_service::run, &_ioservice));
- _ioservice.run();
- cout << "AsyncMessageServer done listening on: " << _port << endl;
- }
-
- void handleAccept( shared_ptr<MessageServerSession> session ,
- const boost::system::error_code& error ) {
- if ( error ) {
- cout << "handleAccept error!" << endl;
- return;
- }
- session->start();
- _accept();
- }
-
- void _accept( ) {
- shared_ptr<MessageServerSession> session( new MessageServerSession( _handler , _ioservice ) );
- _acceptor.async_accept( session->socket() ,
- boost::bind( &AsyncMessageServer::handleAccept,
- this,
- session,
- boost::asio::placeholders::error )
- );
- }
-
- private:
- int _port;
- MessageHandler * _handler;
- io_service _ioservice;
- tcp::endpoint _endpoint;
- tcp::acceptor _acceptor;
- };
-
- MessageServer * createServer( const MessageServer::Options& opts , MessageHandler * handler ) {
- return new AsyncMessageServer( opts , handler );
- }
-
-}
-
-#endif
diff --git a/util/net/message_server_port.cpp b/util/net/message_server_port.cpp
deleted file mode 100644
index ac137125470..00000000000
--- a/util/net/message_server_port.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-// message_server_port.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-
-#ifndef USE_ASIO
-
-#include "message.h"
-#include "message_port.h"
-#include "message_server.h"
-#include "listen.h"
-
-#include "../../db/cmdline.h"
-#include "../../db/lasterror.h"
-#include "../../db/stats/counters.h"
-
-#ifdef __linux__ // TODO: consider making this ifndef _WIN32
-# include <sys/resource.h>
-#endif
-
-namespace mongo {
-
- namespace pms {
-
- MessageHandler * handler;
-
- void threadRun( MessagingPort * inPort) {
- TicketHolderReleaser connTicketReleaser( &connTicketHolder );
-
- setThreadName( "conn" );
-
- assert( inPort );
- inPort->setLogLevel(1);
- scoped_ptr<MessagingPort> p( inPort );
-
- p->postFork();
-
- string otherSide;
-
- Message m;
- try {
- LastError * le = new LastError();
- lastError.reset( le ); // lastError now has ownership
-
- otherSide = p->remoteString();
-
- handler->connected( p.get() );
-
- while ( ! inShutdown() ) {
- m.reset();
- p->clearCounters();
-
- if ( ! p->recv(m) ) {
- if( !cmdLine.quiet )
- log() << "end connection " << otherSide << endl;
- p->shutdown();
- break;
- }
-
- handler->process( m , p.get() , le );
- networkCounter.hit( p->getBytesIn() , p->getBytesOut() );
- }
- }
- catch ( AssertionException& e ) {
- log() << "AssertionException handling request, closing client connection: " << e << endl;
- p->shutdown();
- }
- catch ( SocketException& e ) {
- log() << "SocketException handling request, closing client connection: " << e << endl;
- p->shutdown();
- }
- catch ( const ClockSkewException & ) {
- log() << "ClockSkewException - shutting down" << endl;
- exitCleanly( EXIT_CLOCK_SKEW );
- }
- catch ( const DBException& e ) { // must be right above std::exception to avoid catching subclasses
- log() << "DBException handling request, closing client connection: " << e << endl;
- p->shutdown();
- }
- catch ( std::exception &e ) {
- error() << "Uncaught std::exception: " << e.what() << ", terminating" << endl;
- dbexit( EXIT_UNCAUGHT );
- }
- catch ( ... ) {
- error() << "Uncaught exception, terminating" << endl;
- dbexit( EXIT_UNCAUGHT );
- }
-
- handler->disconnected( p.get() );
- }
-
- }
-
- class PortMessageServer : public MessageServer , public Listener {
- public:
- PortMessageServer( const MessageServer::Options& opts, MessageHandler * handler ) :
- Listener( "" , opts.ipList, opts.port ) {
-
- uassert( 10275 , "multiple PortMessageServer not supported" , ! pms::handler );
- pms::handler = handler;
- }
-
- virtual void accepted(MessagingPort * p) {
-
- if ( ! connTicketHolder.tryAcquire() ) {
- log() << "connection refused because too many open connections: " << connTicketHolder.used() << endl;
-
- // TODO: would be nice if we notified them...
- p->shutdown();
- delete p;
-
- sleepmillis(2); // otherwise we'll hard loop
- return;
- }
-
- try {
-#ifndef __linux__ // TODO: consider making this ifdef _WIN32
- boost::thread thr( boost::bind( &pms::threadRun , p ) );
-#else
- pthread_attr_t attrs;
- pthread_attr_init(&attrs);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
-
- static const size_t STACK_SIZE = 1024*1024; // if we change this we need to update the warning
-
- struct rlimit limits;
- verify(15887, getrlimit(RLIMIT_STACK, &limits) == 0);
- if (limits.rlim_cur > STACK_SIZE) {
- pthread_attr_setstacksize(&attrs, (DEBUG_BUILD
- ? (STACK_SIZE / 2)
- : STACK_SIZE));
- } else if (limits.rlim_cur < 1024*1024) {
- warning() << "Stack size set to " << (limits.rlim_cur/1024) << "KB. We suggest 1MB" << endl;
- }
-
-
- pthread_t thread;
- int failed = pthread_create(&thread, &attrs, (void*(*)(void*)) &pms::threadRun, p);
-
- pthread_attr_destroy(&attrs);
-
- if (failed) {
- log() << "pthread_create failed: " << errnoWithDescription(failed) << endl;
- throw boost::thread_resource_error(); // for consistency with boost::thread
- }
-#endif
- }
- catch ( boost::thread_resource_error& ) {
- connTicketHolder.release();
- log() << "can't create new thread, closing connection" << endl;
-
- p->shutdown();
- delete p;
-
- sleepmillis(2);
- }
- catch ( ... ) {
- connTicketHolder.release();
- log() << "unknown error accepting new socket" << endl;
-
- p->shutdown();
- delete p;
-
- sleepmillis(2);
- }
-
- }
-
- virtual void setAsTimeTracker() {
- Listener::setAsTimeTracker();
- }
-
- void run() {
- initAndListen();
- }
-
- virtual bool useUnixSockets() const { return true; }
- };
-
-
- MessageServer * createServer( const MessageServer::Options& opts , MessageHandler * handler ) {
- return new PortMessageServer( opts , handler );
- }
-
-}
-
-#endif
diff --git a/util/net/miniwebserver.cpp b/util/net/miniwebserver.cpp
deleted file mode 100644
index f0b58569d22..00000000000
--- a/util/net/miniwebserver.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-// miniwebserver.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "miniwebserver.h"
-#include "../hex.h"
-
-#include "pcrecpp.h"
-
-namespace mongo {
-
- MiniWebServer::MiniWebServer(const string& name, const string &ip, int port)
- : Listener(name, ip, port, false)
- {}
-
- string MiniWebServer::parseURL( const char * buf ) {
- const char * urlStart = strchr( buf , ' ' );
- if ( ! urlStart )
- return "/";
-
- urlStart++;
-
- const char * end = strchr( urlStart , ' ' );
- if ( ! end ) {
- end = strchr( urlStart , '\r' );
- if ( ! end ) {
- end = strchr( urlStart , '\n' );
- }
- }
-
- if ( ! end )
- return "/";
-
- int diff = (int)(end-urlStart);
- if ( diff < 0 || diff > 255 )
- return "/";
-
- return string( urlStart , (int)(end-urlStart) );
- }
-
- void MiniWebServer::parseParams( BSONObj & params , string query ) {
- if ( query.size() == 0 )
- return;
-
- BSONObjBuilder b;
- while ( query.size() ) {
-
- string::size_type amp = query.find( "&" );
-
- string cur;
- if ( amp == string::npos ) {
- cur = query;
- query = "";
- }
- else {
- cur = query.substr( 0 , amp );
- query = query.substr( amp + 1 );
- }
-
- string::size_type eq = cur.find( "=" );
- if ( eq == string::npos )
- continue;
-
- b.append( urlDecode(cur.substr(0,eq)) , urlDecode(cur.substr(eq+1) ) );
- }
-
- params = b.obj();
- }
-
- string MiniWebServer::parseMethod( const char * headers ) {
- const char * end = strchr( headers , ' ' );
- if ( ! end )
- return "GET";
- return string( headers , (int)(end-headers) );
- }
-
- const char *MiniWebServer::body( const char *buf ) {
- const char *ret = strstr( buf, "\r\n\r\n" );
- return ret ? ret + 4 : ret;
- }
-
- bool MiniWebServer::fullReceive( const char *buf ) {
- const char *bod = body( buf );
- if ( !bod )
- return false;
- const char *lenString = "Content-Length:";
- const char *lengthLoc = strstr( buf, lenString );
- if ( !lengthLoc )
- return true;
- lengthLoc += strlen( lenString );
- long len = strtol( lengthLoc, 0, 10 );
- if ( long( strlen( bod ) ) == len )
- return true;
- return false;
- }
-
- void MiniWebServer::accepted(Socket sock) {
- sock.postFork();
- sock.setTimeout(8);
- char buf[4096];
- int len = 0;
- while ( 1 ) {
- int left = sizeof(buf) - 1 - len;
- if( left == 0 )
- break;
- int x = sock.unsafe_recv( buf + len , left );
- if ( x <= 0 ) {
- sock.close();
- return;
- }
- len += x;
- buf[ len ] = 0;
- if ( fullReceive( buf ) ) {
- break;
- }
- }
- buf[len] = 0;
-
- string responseMsg;
- int responseCode = 599;
- vector<string> headers;
-
- try {
- doRequest(buf, parseURL( buf ), responseMsg, responseCode, headers, sock.remoteAddr() );
- }
- catch ( std::exception& e ) {
- responseCode = 500;
- responseMsg = "error loading page: ";
- responseMsg += e.what();
- }
- catch ( ... ) {
- responseCode = 500;
- responseMsg = "unknown error loading page";
- }
-
- stringstream ss;
- ss << "HTTP/1.0 " << responseCode;
- if ( responseCode == 200 ) ss << " OK";
- ss << "\r\n";
- if ( headers.empty() ) {
- ss << "Content-Type: text/html\r\n";
- }
- else {
- for ( vector<string>::iterator i = headers.begin(); i != headers.end(); i++ ) {
- assert( strncmp("Content-Length", i->c_str(), 14) );
- ss << *i << "\r\n";
- }
- }
- ss << "Connection: close\r\n";
- ss << "Content-Length: " << responseMsg.size() << "\r\n";
- ss << "\r\n";
- ss << responseMsg;
- string response = ss.str();
-
- try {
- sock.send( response.c_str(), response.size() , "http response" );
- sock.close();
- }
- catch ( SocketException& e ) {
- log(1) << "couldn't send data to http client: " << e << endl;
- }
- }
-
- string MiniWebServer::getHeader( const char * req , string wanted ) {
- const char * headers = strchr( req , '\n' );
- if ( ! headers )
- return "";
- pcrecpp::StringPiece input( headers + 1 );
-
- string name;
- string val;
- pcrecpp::RE re("([\\w\\-]+): (.*?)\r?\n");
- while ( re.Consume( &input, &name, &val) ) {
- if ( name == wanted )
- return val;
- }
- return "";
- }
-
- string MiniWebServer::urlDecode(const char* s) {
- stringstream out;
- while(*s) {
- if (*s == '+') {
- out << ' ';
- }
- else if (*s == '%') {
- out << fromHex(s+1);
- s+=2;
- }
- else {
- out << *s;
- }
- s++;
- }
- return out.str();
- }
-
-} // namespace mongo
diff --git a/util/net/miniwebserver.h b/util/net/miniwebserver.h
deleted file mode 100644
index 1fb6b3f2e65..00000000000
--- a/util/net/miniwebserver.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// miniwebserver.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../../pch.h"
-#include "message.h"
-#include "message_port.h"
-#include "listen.h"
-#include "../../db/jsobj.h"
-
-namespace mongo {
-
- class MiniWebServer : public Listener {
- public:
- MiniWebServer(const string& name, const string &ip, int _port);
- virtual ~MiniWebServer() {}
-
- virtual void doRequest(
- const char *rq, // the full request
- string url,
- // set these and return them:
- string& responseMsg,
- int& responseCode,
- vector<string>& headers, // if completely empty, content-type: text/html will be added
- const SockAddr &from
- ) = 0;
-
- // --- static helpers ----
-
- static void parseParams( BSONObj & params , string query );
-
- static string parseURL( const char * buf );
- static string parseMethod( const char * headers );
- static string getHeader( const char * headers , string name );
- static const char *body( const char *buf );
-
- static string urlDecode(const char* s);
- static string urlDecode(string s) {return urlDecode(s.c_str());}
-
- private:
- void accepted(Socket socket);
- static bool fullReceive( const char *buf );
- };
-
-} // namespace mongo
diff --git a/util/net/sock.cpp b/util/net/sock.cpp
deleted file mode 100644
index a032e50b646..00000000000
--- a/util/net/sock.cpp
+++ /dev/null
@@ -1,782 +0,0 @@
-// @file sock.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "sock.h"
-#include "../background.h"
-
-#if !defined(_WIN32)
-# include <sys/socket.h>
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <sys/un.h>
-# include <netinet/in.h>
-# include <netinet/tcp.h>
-# include <arpa/inet.h>
-# include <errno.h>
-# include <netdb.h>
-# if defined(__openbsd__)
-# include <sys/uio.h>
-# endif
-#endif
-
-#ifdef MONGO_SSL
-#include <openssl/err.h>
-#include <openssl/ssl.h>
-#endif
-
-
-namespace mongo {
-
- static bool ipv6 = false;
- void enableIPv6(bool state) { ipv6 = state; }
- bool IPv6Enabled() { return ipv6; }
-
- void setSockTimeouts(int sock, double secs) {
- struct timeval tv;
- tv.tv_sec = (int)secs;
- tv.tv_usec = (int)((long long)(secs*1000*1000) % (1000*1000));
- bool report = logLevel > 3; // solaris doesn't provide these
- DEV report = true;
-#if defined(_WIN32)
- tv.tv_sec *= 1000; // Windows timeout is a DWORD, in milliseconds.
- int status = setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv.tv_sec, sizeof(DWORD) ) == 0;
- if( report && (status == SOCKET_ERROR) ) log() << "unable to set SO_RCVTIMEO" << endl;
- status = setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv.tv_sec, sizeof(DWORD) ) == 0;
- DEV if( report && (status == SOCKET_ERROR) ) log() << "unable to set SO_SNDTIMEO" << endl;
-#else
- bool ok = setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(tv) ) == 0;
- if( report && !ok ) log() << "unable to set SO_RCVTIMEO" << endl;
- ok = setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, sizeof(tv) ) == 0;
- DEV if( report && !ok ) log() << "unable to set SO_SNDTIMEO" << endl;
-#endif
- }
-
-#if defined(_WIN32)
- void disableNagle(int sock) {
- int x = 1;
- if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &x, sizeof(x)) )
- error() << "disableNagle failed" << endl;
- if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &x, sizeof(x)) )
- error() << "SO_KEEPALIVE failed" << endl;
- }
-#else
-
- void disableNagle(int sock) {
- int x = 1;
-
-#ifdef SOL_TCP
- int level = SOL_TCP;
-#else
- int level = SOL_SOCKET;
-#endif
-
- if ( setsockopt(sock, level, TCP_NODELAY, (char *) &x, sizeof(x)) )
- error() << "disableNagle failed: " << errnoWithDescription() << endl;
-
-#ifdef SO_KEEPALIVE
- if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &x, sizeof(x)) )
- error() << "SO_KEEPALIVE failed: " << errnoWithDescription() << endl;
-
-# ifdef __linux__
- socklen_t len = sizeof(x);
- if ( getsockopt(sock, level, TCP_KEEPIDLE, (char *) &x, &len) )
- error() << "can't get TCP_KEEPIDLE: " << errnoWithDescription() << endl;
-
- if (x > 300) {
- x = 300;
- if ( setsockopt(sock, level, TCP_KEEPIDLE, (char *) &x, sizeof(x)) ) {
- error() << "can't set TCP_KEEPIDLE: " << errnoWithDescription() << endl;
- }
- }
-
- len = sizeof(x); // just in case it changed
- if ( getsockopt(sock, level, TCP_KEEPINTVL, (char *) &x, &len) )
- error() << "can't get TCP_KEEPINTVL: " << errnoWithDescription() << endl;
-
- if (x > 300) {
- x = 300;
- if ( setsockopt(sock, level, TCP_KEEPINTVL, (char *) &x, sizeof(x)) ) {
- error() << "can't set TCP_KEEPINTVL: " << errnoWithDescription() << endl;
- }
- }
-# endif
-#endif
-
- }
-
-#endif
-
- string getAddrInfoStrError(int code) {
-#if !defined(_WIN32)
- return gai_strerror(code);
-#else
- /* gai_strerrorA is not threadsafe on windows. don't use it. */
- return errnoWithDescription(code);
-#endif
- }
-
-
- // --- SockAddr
-
- SockAddr::SockAddr(int sourcePort) {
- memset(as<sockaddr_in>().sin_zero, 0, sizeof(as<sockaddr_in>().sin_zero));
- as<sockaddr_in>().sin_family = AF_INET;
- as<sockaddr_in>().sin_port = htons(sourcePort);
- as<sockaddr_in>().sin_addr.s_addr = htonl(INADDR_ANY);
- addressSize = sizeof(sockaddr_in);
- }
-
- SockAddr::SockAddr(const char * iporhost , int port) {
- if (!strcmp(iporhost, "localhost"))
- iporhost = "127.0.0.1";
-
- if (strchr(iporhost, '/')) {
-#ifdef _WIN32
- uassert(13080, "no unix socket support on windows", false);
-#endif
- uassert(13079, "path to unix socket too long", strlen(iporhost) < sizeof(as<sockaddr_un>().sun_path));
- as<sockaddr_un>().sun_family = AF_UNIX;
- strcpy(as<sockaddr_un>().sun_path, iporhost);
- addressSize = sizeof(sockaddr_un);
- }
- else {
- addrinfo* addrs = NULL;
- addrinfo hints;
- memset(&hints, 0, sizeof(addrinfo));
- hints.ai_socktype = SOCK_STREAM;
- //hints.ai_flags = AI_ADDRCONFIG; // This is often recommended but don't do it. SERVER-1579
- hints.ai_flags |= AI_NUMERICHOST; // first pass tries w/o DNS lookup
- hints.ai_family = (IPv6Enabled() ? AF_UNSPEC : AF_INET);
-
- StringBuilder ss;
- ss << port;
- int ret = getaddrinfo(iporhost, ss.str().c_str(), &hints, &addrs);
-
- // old C compilers on IPv6-capable hosts return EAI_NODATA error
-#ifdef EAI_NODATA
- int nodata = (ret == EAI_NODATA);
-#else
- int nodata = false;
-#endif
- if (ret == EAI_NONAME || nodata) {
- // iporhost isn't an IP address, allow DNS lookup
- hints.ai_flags &= ~AI_NUMERICHOST;
- ret = getaddrinfo(iporhost, ss.str().c_str(), &hints, &addrs);
- }
-
- if (ret) {
- // don't log if this as it is a CRT construction and log() may not work yet.
- if( strcmp("0.0.0.0", iporhost) ) {
- log() << "getaddrinfo(\"" << iporhost << "\") failed: " << gai_strerror(ret) << endl;
- }
- *this = SockAddr(port);
- }
- else {
- //TODO: handle other addresses in linked list;
- assert(addrs->ai_addrlen <= sizeof(sa));
- memcpy(&sa, addrs->ai_addr, addrs->ai_addrlen);
- addressSize = addrs->ai_addrlen;
- freeaddrinfo(addrs);
- }
- }
- }
-
- bool SockAddr::isLocalHost() const {
- switch (getType()) {
- case AF_INET: return getAddr() == "127.0.0.1";
- case AF_INET6: return getAddr() == "::1";
- case AF_UNIX: return true;
- default: return false;
- }
- assert(false);
- return false;
- }
-
- string SockAddr::toString(bool includePort) const {
- string out = getAddr();
- if (includePort && getType() != AF_UNIX && getType() != AF_UNSPEC)
- out += mongoutils::str::stream() << ':' << getPort();
- return out;
- }
-
- sa_family_t SockAddr::getType() const {
- return sa.ss_family;
- }
-
- unsigned SockAddr::getPort() const {
- switch (getType()) {
- case AF_INET: return ntohs(as<sockaddr_in>().sin_port);
- case AF_INET6: return ntohs(as<sockaddr_in6>().sin6_port);
- case AF_UNIX: return 0;
- case AF_UNSPEC: return 0;
- default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return 0;
- }
- }
-
- string SockAddr::getAddr() const {
- switch (getType()) {
- case AF_INET:
- case AF_INET6: {
- const int buflen=128;
- char buffer[buflen];
- int ret = getnameinfo(raw(), addressSize, buffer, buflen, NULL, 0, NI_NUMERICHOST);
- massert(13082, getAddrInfoStrError(ret), ret == 0);
- return buffer;
- }
-
- case AF_UNIX: return (addressSize > 2 ? as<sockaddr_un>().sun_path : "anonymous unix socket");
- case AF_UNSPEC: return "(NONE)";
- default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return "";
- }
- }
-
- bool SockAddr::operator==(const SockAddr& r) const {
- if (getType() != r.getType())
- return false;
-
- if (getPort() != r.getPort())
- return false;
-
- switch (getType()) {
- case AF_INET: return as<sockaddr_in>().sin_addr.s_addr == r.as<sockaddr_in>().sin_addr.s_addr;
- case AF_INET6: return memcmp(as<sockaddr_in6>().sin6_addr.s6_addr, r.as<sockaddr_in6>().sin6_addr.s6_addr, sizeof(in6_addr)) == 0;
- case AF_UNIX: return strcmp(as<sockaddr_un>().sun_path, r.as<sockaddr_un>().sun_path) == 0;
- case AF_UNSPEC: return true; // assume all unspecified addresses are the same
- default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false);
- }
- return false;
- }
-
- bool SockAddr::operator!=(const SockAddr& r) const {
- return !(*this == r);
- }
-
- bool SockAddr::operator<(const SockAddr& r) const {
- if (getType() < r.getType())
- return true;
- else if (getType() > r.getType())
- return false;
-
- if (getPort() < r.getPort())
- return true;
- else if (getPort() > r.getPort())
- return false;
-
- switch (getType()) {
- case AF_INET: return as<sockaddr_in>().sin_addr.s_addr < r.as<sockaddr_in>().sin_addr.s_addr;
- case AF_INET6: return memcmp(as<sockaddr_in6>().sin6_addr.s6_addr, r.as<sockaddr_in6>().sin6_addr.s6_addr, sizeof(in6_addr)) < 0;
- case AF_UNIX: return strcmp(as<sockaddr_un>().sun_path, r.as<sockaddr_un>().sun_path) < 0;
- case AF_UNSPEC: return false;
- default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false);
- }
- return false;
- }
-
- SockAddr unknownAddress( "0.0.0.0", 0 );
-
- // ------ hostname -------------------
-
- string hostbyname(const char *hostname) {
- string addr = SockAddr(hostname, 0).getAddr();
- if (addr == "0.0.0.0")
- return "";
- else
- return addr;
- }
-
- // --- my --
-
- string getHostName() {
- char buf[256];
- int ec = gethostname(buf, 127);
- if ( ec || *buf == 0 ) {
- log() << "can't get this server's hostname " << errnoWithDescription() << endl;
- return "";
- }
- return buf;
- }
-
-
- string _hostNameCached;
- static void _hostNameCachedInit() {
- _hostNameCached = getHostName();
- }
- boost::once_flag _hostNameCachedInitFlags = BOOST_ONCE_INIT;
-
- string getHostNameCached() {
- boost::call_once( _hostNameCachedInit , _hostNameCachedInitFlags );
- return _hostNameCached;
- }
-
- // --------- SocketException ----------
-
-#ifdef MSG_NOSIGNAL
- const int portSendFlags = MSG_NOSIGNAL;
- const int portRecvFlags = MSG_NOSIGNAL;
-#else
- const int portSendFlags = 0;
- const int portRecvFlags = 0;
-#endif
-
- string SocketException::toString() const {
- stringstream ss;
- ss << _ei.code << " socket exception [" << _type << "] ";
-
- if ( _server.size() )
- ss << "server [" << _server << "] ";
-
- if ( _extra.size() )
- ss << _extra;
-
- return ss.str();
- }
-
-
- // ------------ SSLManager -----------------
-
-#ifdef MONGO_SSL
- static unsigned long _ssl_id_callback();
- static void _ssl_locking_callback(int mode, int type, const char *file, int line);
-
- class SSLThreadInfo {
- public:
-
- SSLThreadInfo() {
- _id = ++_next;
- CRYPTO_set_id_callback(_ssl_id_callback);
- CRYPTO_set_locking_callback(_ssl_locking_callback);
- }
-
- ~SSLThreadInfo() {
- CRYPTO_set_id_callback(0);
- }
-
- unsigned long id() const { return _id; }
-
- void lock_callback( int mode, int type, const char *file, int line ) {
- if ( mode & CRYPTO_LOCK ) {
- _mutex[type]->lock();
- }
- else {
- _mutex[type]->unlock();
- }
- }
-
- static void init() {
- while ( (int)_mutex.size() < CRYPTO_num_locks() )
- _mutex.push_back( new SimpleMutex("SSLThreadInfo") );
- }
-
- static SSLThreadInfo* get() {
- SSLThreadInfo* me = _thread.get();
- if ( ! me ) {
- me = new SSLThreadInfo();
- _thread.reset( me );
- }
- return me;
- }
-
- private:
- unsigned _id;
-
- static AtomicUInt _next;
- static vector<SimpleMutex*> _mutex;
- static boost::thread_specific_ptr<SSLThreadInfo> _thread;
- };
-
- static unsigned long _ssl_id_callback() {
- return SSLThreadInfo::get()->id();
- }
- static void _ssl_locking_callback(int mode, int type, const char *file, int line) {
- SSLThreadInfo::get()->lock_callback( mode , type , file , line );
- }
-
- AtomicUInt SSLThreadInfo::_next;
- vector<SimpleMutex*> SSLThreadInfo::_mutex;
- boost::thread_specific_ptr<SSLThreadInfo> SSLThreadInfo::_thread;
-
-
- SSLManager::SSLManager( bool client ) {
- _client = client;
- SSL_library_init();
- SSL_load_error_strings();
- ERR_load_crypto_strings();
-
- _context = SSL_CTX_new( client ? SSLv23_client_method() : SSLv23_server_method() );
- massert( 15864 , mongoutils::str::stream() << "can't create SSL Context: " << ERR_error_string(ERR_get_error(), NULL) , _context );
-
- SSL_CTX_set_options( _context, SSL_OP_ALL);
- SSLThreadInfo::init();
- SSLThreadInfo::get();
- }
-
- void SSLManager::setupPubPriv( const string& privateKeyFile , const string& publicKeyFile ) {
- massert( 15865 ,
- mongoutils::str::stream() << "Can't read SSL certificate from file "
- << publicKeyFile << ":" << ERR_error_string(ERR_get_error(), NULL) ,
- SSL_CTX_use_certificate_file(_context, publicKeyFile.c_str(), SSL_FILETYPE_PEM) );
-
-
- massert( 15866 ,
- mongoutils::str::stream() << "Can't read SSL private key from file "
- << privateKeyFile << " : " << ERR_error_string(ERR_get_error(), NULL) ,
- SSL_CTX_use_PrivateKey_file(_context, privateKeyFile.c_str(), SSL_FILETYPE_PEM) );
- }
-
-
- int SSLManager::password_cb(char *buf,int num, int rwflag,void *userdata){
- SSLManager* sm = (SSLManager*)userdata;
- string pass = sm->_password;
- strcpy(buf,pass.c_str());
- return(pass.size());
- }
-
- void SSLManager::setupPEM( const string& keyFile , const string& password ) {
- _password = password;
-
- massert( 15867 , "Can't read certificate file" , SSL_CTX_use_certificate_chain_file( _context , keyFile.c_str() ) );
-
- SSL_CTX_set_default_passwd_cb_userdata( _context , this );
- SSL_CTX_set_default_passwd_cb( _context, &SSLManager::password_cb );
-
- massert( 15868 , "Can't read key file" , SSL_CTX_use_PrivateKey_file( _context , keyFile.c_str() , SSL_FILETYPE_PEM ) );
- }
-
- SSL * SSLManager::secure( int fd ) {
- SSLThreadInfo::get();
- SSL * ssl = SSL_new( _context );
- massert( 15861 , "can't create SSL" , ssl );
- SSL_set_fd( ssl , fd );
- return ssl;
- }
-
-
-#endif
-
- // ------------ Socket -----------------
-
- Socket::Socket(int fd , const SockAddr& remote) :
- _fd(fd), _remote(remote), _timeout(0) {
- _logLevel = 0;
- _init();
- }
-
- Socket::Socket( double timeout, int ll ) {
- _logLevel = ll;
- _fd = -1;
- _timeout = timeout;
- _init();
- }
-
- void Socket::_init() {
- _bytesOut = 0;
- _bytesIn = 0;
-#ifdef MONGO_SSL
- _ssl = 0;
- _sslAccepted = 0;
-#endif
- }
-
- void Socket::close() {
-#ifdef MONGO_SSL
- if ( _ssl ) {
- SSL_shutdown( _ssl );
- SSL_free( _ssl );
- _ssl = 0;
- }
-#endif
- if ( _fd >= 0 ) {
- closesocket( _fd );
- _fd = -1;
- }
- }
-
-#ifdef MONGO_SSL
- void Socket::secure( SSLManager * ssl ) {
- assert( ssl );
- assert( _fd >= 0 );
- _ssl = ssl->secure( _fd );
- SSL_connect( _ssl );
- }
-
- void Socket::secureAccepted( SSLManager * ssl ) {
- _sslAccepted = ssl;
- }
-#endif
-
- void Socket::postFork() {
-#ifdef MONGO_SSL
- if ( _sslAccepted ) {
- assert( _fd );
- _ssl = _sslAccepted->secure( _fd );
- SSL_accept( _ssl );
- _sslAccepted = 0;
- }
-#endif
- }
-
- class ConnectBG : public BackgroundJob {
- public:
- ConnectBG(int sock, SockAddr remote) : _sock(sock), _remote(remote) { }
-
- void run() { _res = ::connect(_sock, _remote.raw(), _remote.addressSize); }
- string name() const { return "ConnectBG"; }
- int inError() const { return _res; }
-
- private:
- int _sock;
- int _res;
- SockAddr _remote;
- };
-
- bool Socket::connect(SockAddr& remote) {
- _remote = remote;
-
- _fd = socket(remote.getType(), SOCK_STREAM, 0);
- if ( _fd == INVALID_SOCKET ) {
- log(_logLevel) << "ERROR: connect invalid socket " << errnoWithDescription() << endl;
- return false;
- }
-
- if ( _timeout > 0 ) {
- setTimeout( _timeout );
- }
-
- ConnectBG bg(_fd, remote);
- bg.go();
- if ( bg.wait(5000) ) {
- if ( bg.inError() ) {
- close();
- return false;
- }
- }
- else {
- // time out the connect
- close();
- bg.wait(); // so bg stays in scope until bg thread terminates
- return false;
- }
-
- if (remote.getType() != AF_UNIX)
- disableNagle(_fd);
-
-#ifdef SO_NOSIGPIPE
- // osx
- const int one = 1;
- setsockopt( _fd , SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(int));
-#endif
-
- return true;
- }
-
- int Socket::_send( const char * data , int len ) {
-#ifdef MONGO_SSL
- if ( _ssl ) {
- return SSL_write( _ssl , data , len );
- }
-#endif
- return ::send( _fd , data , len , portSendFlags );
- }
-
- // sends all data or throws an exception
- void Socket::send( const char * data , int len, const char *context ) {
- while( len > 0 ) {
- int ret = _send( data , len );
- if ( ret == -1 ) {
-
-#ifdef MONGO_SSL
- if ( _ssl ) {
- log() << "SSL Error ret: " << ret << " err: " << SSL_get_error( _ssl , ret )
- << " " << ERR_error_string(ERR_get_error(), NULL)
- << endl;
- }
-#endif
-
-#if defined(_WIN32)
- if ( WSAGetLastError() == WSAETIMEDOUT && _timeout != 0 ) {
-#else
- if ( ( errno == EAGAIN || errno == EWOULDBLOCK ) && _timeout != 0 ) {
-#endif
- log(_logLevel) << "Socket " << context << " send() timed out " << _remote.toString() << endl;
- throw SocketException( SocketException::SEND_TIMEOUT , remoteString() );
- }
- else {
- SocketException::Type t = SocketException::SEND_ERROR;
- log(_logLevel) << "Socket " << context << " send() "
- << errnoWithDescription() << ' ' << remoteString() << endl;
- throw SocketException( t , remoteString() );
- }
- }
- else {
- _bytesOut += ret;
-
- assert( ret <= len );
- len -= ret;
- data += ret;
- }
- }
- }
-
- void Socket::_send( const vector< pair< char *, int > > &data, const char *context ) {
- for( vector< pair< char *, int > >::const_iterator i = data.begin(); i != data.end(); ++i ) {
- char * data = i->first;
- int len = i->second;
- send( data, len, context );
- }
- }
-
- // sends all data or throws an exception
- void Socket::send( const vector< pair< char *, int > > &data, const char *context ) {
-
-#ifdef MONGO_SSL
- if ( _ssl ) {
- _send( data , context );
- return;
- }
-#endif
-
-#if defined(_WIN32)
- // TODO use scatter/gather api
- _send( data , context );
-#else
- vector< struct iovec > d( data.size() );
- int i = 0;
- for( vector< pair< char *, int > >::const_iterator j = data.begin(); j != data.end(); ++j ) {
- if ( j->second > 0 ) {
- d[ i ].iov_base = j->first;
- d[ i ].iov_len = j->second;
- ++i;
- _bytesOut += j->second;
- }
- }
- struct msghdr meta;
- memset( &meta, 0, sizeof( meta ) );
- meta.msg_iov = &d[ 0 ];
- meta.msg_iovlen = d.size();
-
- while( meta.msg_iovlen > 0 ) {
- int ret = ::sendmsg( _fd , &meta , portSendFlags );
- if ( ret == -1 ) {
- if ( errno != EAGAIN || _timeout == 0 ) {
- log(_logLevel) << "Socket " << context << " send() " << errnoWithDescription() << ' ' << remoteString() << endl;
- throw SocketException( SocketException::SEND_ERROR , remoteString() );
- }
- else {
- log(_logLevel) << "Socket " << context << " send() remote timeout " << remoteString() << endl;
- throw SocketException( SocketException::SEND_TIMEOUT , remoteString() );
- }
- }
- else {
- struct iovec *& i = meta.msg_iov;
- while( ret > 0 ) {
- if ( i->iov_len > unsigned( ret ) ) {
- i->iov_len -= ret;
- i->iov_base = (char*)(i->iov_base) + ret;
- ret = 0;
- }
- else {
- ret -= i->iov_len;
- ++i;
- --(meta.msg_iovlen);
- }
- }
- }
- }
-#endif
- }
-
- void Socket::recv( char * buf , int len ) {
- unsigned retries = 0;
- while( len > 0 ) {
- int ret = unsafe_recv( buf , len );
- if ( ret > 0 ) {
- if ( len <= 4 && ret != len )
- log(_logLevel) << "Socket recv() got " << ret << " bytes wanted len=" << len << endl;
- assert( ret <= len );
- len -= ret;
- buf += ret;
- }
- else if ( ret == 0 ) {
- log(3) << "Socket recv() conn closed? " << remoteString() << endl;
- throw SocketException( SocketException::CLOSED , remoteString() );
- }
- else { /* ret < 0 */
-#if defined(_WIN32)
- int e = WSAGetLastError();
-#else
- int e = errno;
-# if defined(EINTR)
- if( e == EINTR ) {
- if( ++retries == 1 ) {
- log() << "EINTR retry" << endl;
- continue;
- }
- }
-# endif
-#endif
- if ( ( e == EAGAIN
-#if defined(_WIN32)
- || e == WSAETIMEDOUT
-#endif
- ) && _timeout > 0 )
- {
- // this is a timeout
- log(_logLevel) << "Socket recv() timeout " << remoteString() <<endl;
- throw SocketException( SocketException::RECV_TIMEOUT, remoteString() );
- }
-
- log(_logLevel) << "Socket recv() " << errnoWithDescription(e) << " " << remoteString() <<endl;
- throw SocketException( SocketException::RECV_ERROR , remoteString() );
- }
- }
- }
-
- int Socket::unsafe_recv( char *buf, int max ) {
- int x = _recv( buf , max );
- _bytesIn += x;
- return x;
- }
-
-
- int Socket::_recv( char *buf, int max ) {
-#ifdef MONGO_SSL
- if ( _ssl ){
- return SSL_read( _ssl , buf , max );
- }
-#endif
- return ::recv( _fd , buf , max , portRecvFlags );
- }
-
- void Socket::setTimeout( double secs ) {
- setSockTimeouts( _fd, secs );
- }
-
-#if defined(_WIN32)
- struct WinsockInit {
- WinsockInit() {
- WSADATA d;
- if ( WSAStartup(MAKEWORD(2,2), &d) != 0 ) {
- out() << "ERROR: wsastartup failed " << errnoWithDescription() << endl;
- problem() << "ERROR: wsastartup failed " << errnoWithDescription() << endl;
- dbexit( EXIT_NTSERVICE_ERROR );
- }
- }
- } winsock_init;
-#endif
-
-} // namespace mongo
diff --git a/util/net/sock.h b/util/net/sock.h
deleted file mode 100644
index f91c2881d23..00000000000
--- a/util/net/sock.h
+++ /dev/null
@@ -1,256 +0,0 @@
-// @file sock.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../../pch.h"
-
-#include <stdio.h>
-#include <sstream>
-#include "../goodies.h"
-#include "../../db/cmdline.h"
-#include "../mongoutils/str.h"
-
-#ifndef _WIN32
-
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-
-#ifdef __openbsd__
-# include <sys/uio.h>
-#endif
-
-#endif // _WIN32
-
-#ifdef MONGO_SSL
-#include <openssl/ssl.h>
-#endif
-
-namespace mongo {
-
- const int SOCK_FAMILY_UNKNOWN_ERROR=13078;
-
- void disableNagle(int sock);
-
-#if defined(_WIN32)
-
- typedef short sa_family_t;
- typedef int socklen_t;
-
- // This won't actually be used on windows
- struct sockaddr_un {
- short sun_family;
- char sun_path[108]; // length from unix header
- };
-
-#else // _WIN32
-
- inline void closesocket(int s) { close(s); }
- const int INVALID_SOCKET = -1;
- typedef int SOCKET;
-
-#endif // _WIN32
-
- inline string makeUnixSockPath(int port) {
- return mongoutils::str::stream() << cmdLine.socket << "/mongodb-" << port << ".sock";
- }
-
- // If an ip address is passed in, just return that. If a hostname is passed
- // in, look up its ip and return that. Returns "" on failure.
- string hostbyname(const char *hostname);
-
- void enableIPv6(bool state=true);
- bool IPv6Enabled();
- void setSockTimeouts(int sock, double secs);
-
- /**
- * wrapped around os representation of network address
- */
- struct SockAddr {
- SockAddr() {
- addressSize = sizeof(sa);
- memset(&sa, 0, sizeof(sa));
- sa.ss_family = AF_UNSPEC;
- }
- SockAddr(int sourcePort); /* listener side */
- SockAddr(const char *ip, int port); /* EndPoint (remote) side, or if you want to specify which interface locally */
-
- template <typename T> T& as() { return *(T*)(&sa); }
- template <typename T> const T& as() const { return *(const T*)(&sa); }
-
- string toString(bool includePort=true) const;
-
- /**
- * @return one of AF_INET, AF_INET6, or AF_UNIX
- */
- sa_family_t getType() const;
-
- unsigned getPort() const;
-
- string getAddr() const;
-
- bool isLocalHost() const;
-
- bool operator==(const SockAddr& r) const;
-
- bool operator!=(const SockAddr& r) const;
-
- bool operator<(const SockAddr& r) const;
-
- const sockaddr* raw() const {return (sockaddr*)&sa;}
- sockaddr* raw() {return (sockaddr*)&sa;}
-
- socklen_t addressSize;
- private:
- struct sockaddr_storage sa;
- };
-
- extern SockAddr unknownAddress; // ( "0.0.0.0", 0 )
-
- /** this is not cache and does a syscall */
- string getHostName();
-
- /** this is cached, so if changes during the process lifetime
- * will be stale */
- string getHostNameCached();
-
- /**
- * thrown by Socket and SockAddr
- */
- class SocketException : public DBException {
- public:
- const enum Type { CLOSED , RECV_ERROR , SEND_ERROR, RECV_TIMEOUT, SEND_TIMEOUT, FAILED_STATE, CONNECT_ERROR } _type;
-
- SocketException( Type t , string server , int code = 9001 , string extra="" )
- : DBException( "socket exception" , code ) , _type(t) , _server(server), _extra(extra){ }
- virtual ~SocketException() throw() {}
-
- bool shouldPrint() const { return _type != CLOSED; }
- virtual string toString() const;
-
- private:
- string _server;
- string _extra;
- };
-
-#ifdef MONGO_SSL
- class SSLManager : boost::noncopyable {
- public:
- SSLManager( bool client );
-
- void setupPEM( const string& keyFile , const string& password );
- void setupPubPriv( const string& privateKeyFile , const string& publicKeyFile );
-
- /**
- * creates an SSL context to be used for this file descriptor
- * caller should delete
- */
- SSL * secure( int fd );
-
- static int password_cb( char *buf,int num, int rwflag,void *userdata );
-
- private:
- bool _client;
- SSL_CTX* _context;
- string _password;
- };
-#endif
-
- /**
- * thin wrapped around file descriptor and system calls
- * todo: ssl
- */
- class Socket {
- public:
- Socket(int sock, const SockAddr& farEnd);
-
- /** In some cases the timeout will actually be 2x this value - eg we do a partial send,
- then the timeout fires, then we try to send again, then the timeout fires again with
- no data sent, then we detect that the other side is down.
-
- Generally you don't want a timeout, you should be very prepared for errors if you set one.
- */
- Socket(double so_timeout = 0, int logLevel = 0 );
-
- bool connect(SockAddr& farEnd);
- void close();
-
- void send( const char * data , int len, const char *context );
- void send( const vector< pair< char *, int > > &data, const char *context );
-
- // recv len or throw SocketException
- void recv( char * data , int len );
- int unsafe_recv( char *buf, int max );
-
- int getLogLevel() const { return _logLevel; }
- void setLogLevel( int ll ) { _logLevel = ll; }
-
- SockAddr remoteAddr() const { return _remote; }
- string remoteString() const { return _remote.toString(); }
- unsigned remotePort() const { return _remote.getPort(); }
-
- void clearCounters() { _bytesIn = 0; _bytesOut = 0; }
- long long getBytesIn() const { return _bytesIn; }
- long long getBytesOut() const { return _bytesOut; }
-
- void setTimeout( double secs );
-
-#ifdef MONGO_SSL
- /** secures inline */
- void secure( SSLManager * ssl );
-
- void secureAccepted( SSLManager * ssl );
-#endif
-
- /**
- * call this after a fork for server sockets
- */
- void postFork();
-
- private:
- void _init();
- /** raw send, same semantics as ::send */
- int _send( const char * data , int len );
-
- /** sends dumbly, just each buffer at a time */
- void _send( const vector< pair< char *, int > > &data, const char *context );
-
- /** raw recv, same semantics as ::recv */
- int _recv( char * buf , int max );
-
- int _fd;
- SockAddr _remote;
- double _timeout;
-
- long long _bytesIn;
- long long _bytesOut;
-
-#ifdef MONGO_SSL
- SSL* _ssl;
- SSLManager * _sslAccepted;
-#endif
-
- protected:
- int _logLevel; // passed to log() when logging errors
-
- };
-
-
-} // namespace mongo
diff --git a/util/ntservice.cpp b/util/ntservice.cpp
deleted file mode 100644
index c9723a10d4f..00000000000
--- a/util/ntservice.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// ntservice.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "ntservice.h"
-#include "../db/client.h"
-#include "winutil.h"
-#include "text.h"
-#include <direct.h>
-
-#if defined(_WIN32)
-
-namespace mongo {
-
- void shutdownServer();
-
- SERVICE_STATUS_HANDLE ServiceController::_statusHandle = NULL;
- std::wstring ServiceController::_serviceName;
- ServiceCallback ServiceController::_serviceCallback = NULL;
-
- ServiceController::ServiceController() {}
-
- bool initService();
-
- // returns true if the service is started.
- bool serviceParamsCheck( program_options::variables_map& params, const std::string dbpath, int argc, char* argv[] ) {
- bool installService = false;
- bool removeService = false;
- bool reinstallService = false;
- bool startService = false;
-
- std::wstring windowsServiceName = L"MongoDB";
- std::wstring windowsServiceDisplayName = L"Mongo DB";
- std::wstring windowsServiceDescription = L"Mongo DB Server";
- std::wstring windowsServiceUser = L"";
- std::wstring windowsServicePassword = L"";
-
- if (params.count("install")) {
- if ( ! params.count( "logpath" ) ) {
- cerr << "--install has to be used with --logpath" << endl;
- ::exit(-1);
- }
- installService = true;
- }
- if (params.count("reinstall")) {
- if ( ! params.count( "logpath" ) ) {
- cerr << "--reinstall has to be used with --logpath" << endl;
- ::exit(-1);
- }
- reinstallService = true;
- }
- if (params.count("remove")) {
- removeService = true;
- }
- if (params.count("service")) {
- startService = true;
- }
-
- if (params.count("serviceName")) {
- string x = params["serviceName"].as<string>();
- windowsServiceName = wstring(x.size(),L' ');
- for ( size_t i=0; i<x.size(); i++) {
- windowsServiceName[i] = x[i];
- }
- }
- if (params.count("serviceDisplayName")) {
- string x = params["serviceDisplayName"].as<string>();
- windowsServiceDisplayName = wstring(x.size(),L' ');
- for ( size_t i=0; i<x.size(); i++) {
- windowsServiceDisplayName[i] = x[i];
- }
- }
- if (params.count("serviceDescription")) {
- string x = params["serviceDescription"].as<string>();
- windowsServiceDescription = wstring(x.size(),L' ');
- for ( size_t i=0; i<x.size(); i++) {
- windowsServiceDescription[i] = x[i];
- }
- }
- if (params.count("serviceUser")) {
- string x = params["serviceUser"].as<string>();
- windowsServiceUser = wstring(x.size(),L' ');
- for ( size_t i=0; i<x.size(); i++) {
- windowsServiceUser[i] = x[i];
- }
- }
- if (params.count("servicePassword")) {
- string x = params["servicePassword"].as<string>();
- windowsServicePassword = wstring(x.size(),L' ');
- for ( size_t i=0; i<x.size(); i++) {
- windowsServicePassword[i] = x[i];
- }
- }
-
- if ( reinstallService ) {
- ServiceController::removeService( windowsServiceName );
- }
- if ( installService || reinstallService ) {
- if ( !ServiceController::installService( windowsServiceName , windowsServiceDisplayName, windowsServiceDescription, windowsServiceUser, windowsServicePassword, dbpath, argc, argv ) )
- dbexit( EXIT_NTSERVICE_ERROR );
- dbexit( EXIT_CLEAN );
- }
- else if ( removeService ) {
- if ( !ServiceController::removeService( windowsServiceName ) )
- dbexit( EXIT_NTSERVICE_ERROR );
- dbexit( EXIT_CLEAN );
- }
- else if ( startService ) {
- if ( !ServiceController::startService( windowsServiceName , mongo::initService ) )
- dbexit( EXIT_NTSERVICE_ERROR );
- return true;
- }
- return false;
- }
-
- bool ServiceController::installService( const std::wstring& serviceName, const std::wstring& displayName, const std::wstring& serviceDesc, const std::wstring& serviceUser, const std::wstring& servicePassword, const std::string dbpath, int argc, char* argv[] ) {
- assert(argc >= 1);
-
- stringstream commandLine;
-
- char exePath[1024];
- GetModuleFileNameA( NULL, exePath, sizeof exePath );
- commandLine << '"' << exePath << "\" ";
-
- for ( int i = 1; i < argc; i++ ) {
- std::string arg( argv[ i ] );
- // replace install command to indicate process is being started as a service
- if ( arg == "--install" || arg == "--reinstall" ) {
- arg = "--service";
- }
- else if ( arg == "--dbpath" && i + 1 < argc ) {
- commandLine << arg << " \"" << dbpath << "\" ";
- i++;
- continue;
- }
- else if ( arg == "--logpath" && i + 1 < argc ) {
- commandLine << arg << " \"" << argv[i+1] << "\" ";
- i++;
- continue;
- }
- else if ( arg.length() > 9 && arg.substr(0, 9) == "--service" ) {
- // Strip off --service(Name|User|Password) arguments
- i++;
- continue;
- }
- commandLine << arg << " ";
- }
-
- SC_HANDLE schSCManager = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
- if ( schSCManager == NULL ) {
- DWORD err = ::GetLastError();
- cerr << "Error connecting to the Service Control Manager: " << GetWinErrMsg(err) << endl;
- return false;
- }
-
- // Make sure servise doesn't already exist.
- // TODO: Check to see if service is in "Deleting" status, suggest the user close down Services MMC snap-ins.
- SC_HANDLE schService = ::OpenService( schSCManager, serviceName.c_str(), SERVICE_ALL_ACCESS );
- if ( schService != NULL ) {
- cerr << "There is already a service named " << toUtf8String(serviceName) << ". Aborting" << endl;
- ::CloseServiceHandle( schService );
- ::CloseServiceHandle( schSCManager );
- return false;
- }
- std::basic_ostringstream< TCHAR > commandLineWide;
- commandLineWide << commandLine.str().c_str();
-
- cerr << "Creating service " << toUtf8String(serviceName) << "." << endl;
-
- // create new service
- schService = ::CreateService( schSCManager, serviceName.c_str(), displayName.c_str(),
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
- commandLineWide.str().c_str(), NULL, NULL, L"\0\0", NULL, NULL );
- if ( schService == NULL ) {
- DWORD err = ::GetLastError();
- cerr << "Error creating service: " << GetWinErrMsg(err) << endl;
- ::CloseServiceHandle( schSCManager );
- return false;
- }
-
- cerr << "Service creation successful." << endl;
- cerr << "Service can be started from the command line via 'net start \"" << toUtf8String(serviceName) << "\"'." << endl;
-
- bool serviceInstalled;
-
- // TODO: If neccessary grant user "Login as a Service" permission.
- if ( !serviceUser.empty() ) {
- std::wstring actualServiceUser;
- if ( serviceUser.find(L"\\") == string::npos ) {
- actualServiceUser = L".\\" + serviceUser;
- }
- else {
- actualServiceUser = serviceUser;
- }
-
- cerr << "Setting service login credentials. User: " << toUtf8String(actualServiceUser) << endl;
- serviceInstalled = ::ChangeServiceConfig( schService, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, actualServiceUser.c_str(), servicePassword.c_str(), NULL );
- if ( !serviceInstalled ) {
- cerr << "Setting service login failed. Service has 'LocalService' permissions." << endl;
- }
- }
-
- // set the service description
- SERVICE_DESCRIPTION serviceDescription;
- serviceDescription.lpDescription = (LPTSTR)serviceDesc.c_str();
- serviceInstalled = ::ChangeServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, &serviceDescription );
-
-
- if ( serviceInstalled ) {
- SC_ACTION aActions[ 3 ] = { { SC_ACTION_RESTART, 0 }, { SC_ACTION_RESTART, 0 }, { SC_ACTION_RESTART, 0 } };
-
- SERVICE_FAILURE_ACTIONS serviceFailure;
- ZeroMemory( &serviceFailure, sizeof( SERVICE_FAILURE_ACTIONS ) );
- serviceFailure.cActions = 3;
- serviceFailure.lpsaActions = aActions;
-
- // set service recovery options
- serviceInstalled = ::ChangeServiceConfig2( schService, SERVICE_CONFIG_FAILURE_ACTIONS, &serviceFailure );
-
- }
- else {
- cerr << "Could not set service description. Check the event log for more details." << endl;
- }
-
- ::CloseServiceHandle( schService );
- ::CloseServiceHandle( schSCManager );
-
- return serviceInstalled;
- }
-
- bool ServiceController::removeService( const std::wstring& serviceName ) {
- SC_HANDLE schSCManager = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
- if ( schSCManager == NULL ) {
- DWORD err = ::GetLastError();
- cerr << "Error connecting to the Service Control Manager: " << GetWinErrMsg(err) << endl;
- return false;
- }
-
- SC_HANDLE schService = ::OpenService( schSCManager, serviceName.c_str(), SERVICE_ALL_ACCESS );
- if ( schService == NULL ) {
- cerr << "Could not find a service named " << toUtf8String(serviceName) << " to uninstall." << endl;
- ::CloseServiceHandle( schSCManager );
- return false;
- }
-
- SERVICE_STATUS serviceStatus;
-
- // stop service if its running
- if ( ::ControlService( schService, SERVICE_CONTROL_STOP, &serviceStatus ) ) {
- cerr << "Service " << toUtf8String(serviceName) << " is currently running. Stopping service." << endl;
- while ( ::QueryServiceStatus( schService, &serviceStatus ) ) {
- if ( serviceStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
- Sleep( 1000 );
- }
- else { break; }
- }
- cerr << "Service stopped." << endl;
- }
-
- cerr << "Deleting service " << toUtf8String(serviceName) << "." << endl;
- bool serviceRemoved = ::DeleteService( schService );
-
- ::CloseServiceHandle( schService );
- ::CloseServiceHandle( schSCManager );
-
- if (serviceRemoved) {
- cerr << "Service deleted successfully." << endl;
- }
- else {
- cerr << "Failed to delete service." << endl;
- }
-
- return serviceRemoved;
- }
-
- bool ServiceController::startService( const std::wstring& serviceName, ServiceCallback startService ) {
- _serviceName = serviceName;
- _serviceCallback = startService;
-
- SERVICE_TABLE_ENTRY dispTable[] = {
- { (LPTSTR)serviceName.c_str(), (LPSERVICE_MAIN_FUNCTION)ServiceController::initService },
- { NULL, NULL }
- };
-
- return StartServiceCtrlDispatcher( dispTable );
- }
-
- bool ServiceController::reportStatus( DWORD reportState, DWORD waitHint ) {
- if ( _statusHandle == NULL )
- return false;
-
- static DWORD checkPoint = 1;
-
- SERVICE_STATUS ssStatus;
-
- DWORD dwControlsAccepted;
- switch ( reportState ) {
- case SERVICE_START_PENDING:
- case SERVICE_STOP_PENDING:
- case SERVICE_STOPPED:
- dwControlsAccepted = 0;
- break;
- default:
- dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
- break;
- }
-
- ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- ssStatus.dwServiceSpecificExitCode = 0;
- ssStatus.dwControlsAccepted = dwControlsAccepted;
- ssStatus.dwCurrentState = reportState;
- ssStatus.dwWin32ExitCode = NO_ERROR;
- ssStatus.dwWaitHint = waitHint;
- ssStatus.dwCheckPoint = ( reportState == SERVICE_RUNNING || reportState == SERVICE_STOPPED ) ? 0 : checkPoint++;
-
- return SetServiceStatus( _statusHandle, &ssStatus );
- }
-
- void WINAPI ServiceController::initService( DWORD argc, LPTSTR *argv ) {
- _statusHandle = RegisterServiceCtrlHandler( _serviceName.c_str(), serviceCtrl );
- if ( !_statusHandle )
- return;
-
- reportStatus( SERVICE_START_PENDING, 1000 );
-
- _serviceCallback();
- dbexit( EXIT_CLEAN );
-
- reportStatus( SERVICE_STOPPED );
- }
-
- static void serviceShutdown( const char* controlCodeName ) {
- Client::initThread( "serviceShutdown" );
- log() << "got " << controlCodeName << " request from Windows Service Controller, " <<
- ( inShutdown() ? "already in shutdown" : "will terminate after current cmd ends" ) << endl;
- ServiceController::reportStatus( SERVICE_STOP_PENDING );
- if ( ! inShutdown() ) {
- exitCleanly( EXIT_WINDOWS_SERVICE_STOP );
- ServiceController::reportStatus( SERVICE_STOPPED );
- }
- }
-
- void WINAPI ServiceController::serviceCtrl( DWORD ctrlCode ) {
- switch ( ctrlCode ) {
- case SERVICE_CONTROL_STOP:
- serviceShutdown( "SERVICE_CONTROL_STOP" );
- break;
- case SERVICE_CONTROL_SHUTDOWN:
- serviceShutdown( "SERVICE_CONTROL_SHUTDOWN" );
- break;
- }
- }
-
-} // namespace mongo
-
-#endif
diff --git a/util/ntservice.h b/util/ntservice.h
deleted file mode 100644
index 4958d0395aa..00000000000
--- a/util/ntservice.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// ntservice.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#if defined(_WIN32)
-#include <windows.h>
-
-namespace mongo {
-
- typedef bool ( *ServiceCallback )( void );
- bool serviceParamsCheck( program_options::variables_map& params, const std::string dbpath, int argc, char* argv[] );
-
- class ServiceController {
- public:
- ServiceController();
- virtual ~ServiceController() {}
-
- static bool installService( const std::wstring& serviceName, const std::wstring& displayName, const std::wstring& serviceDesc, const std::wstring& serviceUser, const std::wstring& servicePassword, const std::string dbpath, int argc, char* argv[] );
- static bool removeService( const std::wstring& serviceName );
- static bool startService( const std::wstring& serviceName, ServiceCallback startService );
- static bool reportStatus( DWORD reportState, DWORD waitHint = 0 );
-
- static void WINAPI initService( DWORD argc, LPTSTR *argv );
- static void WINAPI serviceCtrl( DWORD ctrlCode );
-
- protected:
- static std::wstring _serviceName;
- static SERVICE_STATUS_HANDLE _statusHandle;
- static ServiceCallback _serviceCallback;
- };
-
-} // namespace mongo
-
-#endif
diff --git a/util/optime.h b/util/optime.h
deleted file mode 100644
index 9f78fda6d40..00000000000
--- a/util/optime.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// optime.h - OpTime class
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../db/concurrency.h"
-
-namespace mongo {
- void exitCleanly( ExitCode code );
-
- struct ClockSkewException : public DBException {
- ClockSkewException() : DBException( "clock skew exception" , 20001 ) {}
- };
-
- /* replsets used to use RSOpTime.
- M/S uses OpTime.
- But this is useable from both.
- */
- typedef unsigned long long ReplTime;
-
- /* Operation sequence #. A combination of current second plus an ordinal value.
- */
-#pragma pack(4)
- class OpTime {
- unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian
- unsigned secs;
- static OpTime last;
- static OpTime skewed();
- public:
- static void setLast(const Date_t &date) {
- last = OpTime(date);
- }
- unsigned getSecs() const {
- return secs;
- }
- unsigned getInc() const {
- return i;
- }
- OpTime(Date_t date) {
- reinterpret_cast<unsigned long long&>(*this) = date.millis;
- dassert( (int)secs >= 0 );
- }
- OpTime(ReplTime x) {
- reinterpret_cast<unsigned long long&>(*this) = x;
- dassert( (int)secs >= 0 );
- }
- OpTime(unsigned a, unsigned b) {
- secs = a;
- i = b;
- dassert( (int)secs >= 0 );
- }
- OpTime( const OpTime& other ) {
- secs = other.secs;
- i = other.i;
- dassert( (int)secs >= 0 );
- }
- OpTime() {
- secs = 0;
- i = 0;
- }
- // it isn't generally safe to not be locked for this. so use now(). some tests use this.
- static OpTime now_inlock() {
- unsigned t = (unsigned) time(0);
- if ( last.secs == t ) {
- last.i++;
- return last;
- }
- if ( t < last.secs ) {
- return skewed(); // separate function to keep out of the hot code path
- }
- last = OpTime(t, 1);
- return last;
- }
- static OpTime now() {
- DEV dbMutex.assertWriteLocked();
- return now_inlock();
- }
-
- /* We store OpTime's in the database as BSON Date datatype -- we needed some sort of
- 64 bit "container" for these values. While these are not really "Dates", that seems a
- better choice for now than say, Number, which is floating point. Note the BinData type
- is perhaps the cleanest choice, lacking a true unsigned64 datatype, but BinData has 5
- bytes of overhead.
- */
- unsigned long long asDate() const {
- return reinterpret_cast<const unsigned long long*>(&i)[0];
- }
- long long asLL() const {
- return reinterpret_cast<const long long*>(&i)[0];
- }
-
- bool isNull() const { return secs == 0; }
-
- string toStringLong() const {
- char buf[64];
- time_t_to_String(secs, buf);
- stringstream ss;
- ss << time_t_to_String_short(secs) << ' ';
- ss << hex << secs << ':' << i;
- return ss.str();
- }
-
- string toStringPretty() const {
- stringstream ss;
- ss << time_t_to_String_short(secs) << ':' << hex << i;
- return ss.str();
- }
-
- string toString() const {
- stringstream ss;
- ss << hex << secs << ':' << i;
- return ss.str();
- }
-
- bool operator==(const OpTime& r) const {
- return i == r.i && secs == r.secs;
- }
- bool operator!=(const OpTime& r) const {
- return !(*this == r);
- }
- bool operator<(const OpTime& r) const {
- if ( secs != r.secs )
- return secs < r.secs;
- return i < r.i;
- }
- bool operator<=(const OpTime& r) const {
- return *this < r || *this == r;
- }
- bool operator>(const OpTime& r) const {
- return !(*this <= r);
- }
- bool operator>=(const OpTime& r) const {
- return !(*this < r);
- }
- };
-#pragma pack()
-
-} // namespace mongo
diff --git a/util/password.cpp b/util/password.cpp
deleted file mode 100644
index 18164c3aa0a..00000000000
--- a/util/password.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "password.h"
-#include <iostream>
-
-#ifndef _WIN32
-#include <termios.h>
-#endif
-
-using namespace std;
-
-namespace mongo {
-
- string askPassword() {
-
- std::string password;
- cout << "Enter password: ";
-#ifndef _WIN32
- const int stdinfd = 0;
- termios termio;
- tcflag_t old = 0;
- if ( isatty( stdinfd ) ) {
- int i = tcgetattr( stdinfd, &termio );
- if( i == -1 ) {
- cerr << "Cannot get terminal attributes " << errnoWithDescription() << endl;
- return string();
- }
- old = termio.c_lflag;
- termio.c_lflag &= ~ECHO;
- i = tcsetattr( stdinfd, TCSANOW, &termio );
- if( i == -1 ) {
- cerr << "Cannot set terminal attributes " << errnoWithDescription() << endl;
- return string();
- }
- }
-
- getline( cin, password );
-
- if ( isatty( stdinfd ) ) {
- termio.c_lflag = old;
- int i = tcsetattr( stdinfd, TCSANOW, &termio );
- if( i == -1 ) {
- cerr << "Cannot set terminal attributes " << errnoWithDescription() << endl;
- return string();
- }
- }
-#else
- HANDLE stdinh = GetStdHandle( STD_INPUT_HANDLE );
- if ( stdinh == INVALID_HANDLE_VALUE) {
- cerr << "Cannot get stdin handle " << GetLastError() << "\n";
- return string();
- }
-
- DWORD old;
- if ( !GetConsoleMode( stdinh, &old ) ) {
- cerr << "Cannot get console mode " << GetLastError() << "\n";
- return string();
- }
-
- DWORD noecho = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
- if ( !SetConsoleMode( stdinh, noecho ) ) {
- cerr << "Cannot set console mode " << GetLastError() << "\n";
- return string();
- }
-
- getline( cin, password );
-
- if ( !SetConsoleMode( stdinh, old ) ) {
- cerr << "Cannot set console mode " << GetLastError() << "\n";
- return string();
- }
-#endif
- cout << "\n";
- return password;
- }
-}
diff --git a/util/password.h b/util/password.h
deleted file mode 100644
index 519f712ee7e..00000000000
--- a/util/password.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#pragma once
-
-#include <boost/program_options.hpp>
-#include <string>
-
-namespace mongo {
-
- struct PasswordValue : public boost::program_options::typed_value<std::string> {
-
- PasswordValue( std::string* val )
- : boost::program_options::typed_value<std::string>( val ) { }
-
- unsigned min_tokens() const {
- return 0;
- }
-
- unsigned max_tokens() const {
- return 1;
- }
-
- bool is_required() const {
- return false;
- }
-
- void xparse( boost::any& value_store,
- const std::vector<std::string>& new_tokens ) const {
- if ( !value_store.empty() )
-#if BOOST_VERSION >= 104200
- boost::throw_exception( boost::program_options::validation_error( boost::program_options::validation_error::multiple_values_not_allowed ) );
-#else
- boost::throw_exception( boost::program_options::validation_error( "multiple values not allowed" ) );
-#endif
- else if ( !new_tokens.empty() )
- boost::program_options::typed_value<std::string>::xparse
- (value_store, new_tokens);
- else
- value_store = std::string();
- }
-
- };
-
- std::string askPassword();
-
-}
diff --git a/util/paths.h b/util/paths.h
deleted file mode 100644
index 2297a9a2f90..00000000000
--- a/util/paths.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// @file paths.h
-// file paths and directory handling
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "mongoutils/str.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-namespace mongo {
-
- using namespace mongoutils;
-
- extern string dbpath;
-
- /** this is very much like a boost::path. however, we define a new type to get some type
- checking. if you want to say 'my param MUST be a relative path", use this.
- */
- struct RelativePath {
- string _p;
-
- bool empty() const { return _p.empty(); }
-
- static RelativePath fromRelativePath(string f) {
- RelativePath rp;
- rp._p = f;
- return rp;
- }
-
- /** from a full path */
- static RelativePath fromFullPath(path f) {
- path dbp(dbpath); // normalizes / and backslash
- string fullpath = f.string();
- string relative = str::after(fullpath, dbp.string());
- if( relative.empty() ) {
- log() << "warning file is not under db path? " << fullpath << ' ' << dbp.string() << endl;
- RelativePath rp;
- rp._p = fullpath;
- return rp;
- }
- /*uassert(13600,
- str::stream() << "file path is not under the db path? " << fullpath << ' ' << dbpath,
- relative != fullpath);*/
- if( str::startsWith(relative, "/") || str::startsWith(relative, "\\") ) {
- relative.erase(0, 1);
- }
- RelativePath rp;
- rp._p = relative;
- return rp;
- }
-
- string toString() const { return _p; }
-
- bool operator!=(const RelativePath& r) const { return _p != r._p; }
- bool operator==(const RelativePath& r) const { return _p == r._p; }
- bool operator<(const RelativePath& r) const { return _p < r._p; }
-
- string asFullPath() const {
- path x(dbpath);
- x /= _p;
- return x.string();
- }
-
- };
-
- inline dev_t getPartition(const string& path){
- struct stat stats;
-
- if (stat(path.c_str(), &stats) != 0){
- uasserted(13646, str::stream() << "stat() failed for file: " << path << " " << errnoWithDescription());
- }
-
- return stats.st_dev;
- }
-
- inline bool onSamePartition(const string& path1, const string& path2){
- dev_t dev1 = getPartition(path1);
- dev_t dev2 = getPartition(path2);
-
- return dev1 == dev2;
- }
-
- inline void flushMyDirectory(const boost::filesystem::path& file){
-#ifdef __linux__ // this isn't needed elsewhere
- massert(13652, str::stream() << "Couldn't find parent dir for file: " << file.string(), file.has_branch_path());
- boost::filesystem::path dir = file.branch_path(); // parent_path in new boosts
-
- log(1) << "flushing directory " << dir.string() << endl;
-
- int fd = ::open(dir.string().c_str(), O_RDONLY); // DO NOT THROW OR ASSERT BEFORE CLOSING
- massert(13650, str::stream() << "Couldn't open directory '" << dir.string() << "' for flushing: " << errnoWithDescription(), fd >= 0);
- if (fsync(fd) != 0){
- int e = errno;
- close(fd);
- massert(13651, str::stream() << "Couldn't fsync directory '" << dir.string() << "': " << errnoWithDescription(e), false);
- }
- close(fd);
-#endif
- }
-
-}
diff --git a/util/processinfo.cpp b/util/processinfo.cpp
deleted file mode 100644
index 2d5b6e3c3ad..00000000000
--- a/util/processinfo.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// processinfo.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "processinfo.h"
-#include "mmap.h"
-
-#include <iostream>
-using namespace std;
-
-namespace mongo {
-
- class PidFileWiper {
- public:
- ~PidFileWiper() {
- ofstream out( path.c_str() , ios_base::out );
- out.close();
- }
-
- void write( const string& p ) {
- path = p;
- ofstream out( path.c_str() , ios_base::out );
- out << getpid() << endl;
- out.close();
- }
-
- string path;
- } pidFileWiper;
-
- void writePidFile( const string& path ) {
- pidFileWiper.write( path );
- }
-
- void printMemInfo( const char * where ) {
- cout << "mem info: ";
- if ( where )
- cout << where << " ";
- ProcessInfo pi;
- if ( ! pi.supported() ) {
- cout << " not supported" << endl;
- return;
- }
-
- cout << "vsize: " << pi.getVirtualMemorySize() << " resident: " << pi.getResidentSize() << " mapped: " << ( MemoryMappedFile::totalMappedLength() / ( 1024 * 1024 ) ) << endl;
- }
-
-
-}
diff --git a/util/processinfo.h b/util/processinfo.h
deleted file mode 100644
index 5272831eb74..00000000000
--- a/util/processinfo.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// processinfo.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <sys/types.h>
-#include <string>
-
-#ifndef _WIN32
-#include <unistd.h>
-#else
-typedef int pid_t;
-int getpid();
-#endif
-
-namespace mongo {
-
- class BSONObjBuilder;
-
- class ProcessInfo {
- public:
- ProcessInfo( pid_t pid = getpid() );
- ~ProcessInfo();
-
- /**
- * @return mbytes
- */
- int getVirtualMemorySize();
-
- /**
- * @return mbytes
- */
- int getResidentSize();
-
- /**
- * Append platform-specific data to obj
- */
- void getExtraInfo(BSONObjBuilder& info);
-
- bool supported();
-
- static bool blockCheckSupported();
- static bool blockInMemory( char * start );
-
- private:
- pid_t _pid;
- };
-
- void writePidFile( const std::string& path );
-
- void printMemInfo( const char * whereContextStr = 0 );
-
-}
diff --git a/util/processinfo_darwin.cpp b/util/processinfo_darwin.cpp
deleted file mode 100644
index 9f73cbffd4f..00000000000
--- a/util/processinfo_darwin.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-// processinfo_darwin.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../pch.h"
-#include "processinfo.h"
-#include "log.h"
-
-#include <mach/vm_statistics.h>
-#include <mach/task_info.h>
-#include <mach/mach_init.h>
-#include <mach/mach_host.h>
-#include <mach/mach_traps.h>
-#include <mach/task.h>
-#include <mach/vm_map.h>
-#include <mach/shared_region.h>
-#include <iostream>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-
-using namespace std;
-
-namespace mongo {
-
- ProcessInfo::ProcessInfo( pid_t pid ) : _pid( pid ) {
- }
-
- ProcessInfo::~ProcessInfo() {
- }
-
- bool ProcessInfo::supported() {
- return true;
- }
-
- int ProcessInfo::getVirtualMemorySize() {
- task_t result;
-
- mach_port_t task;
-
- if ( ( result = task_for_pid( mach_task_self() , _pid , &task) ) != KERN_SUCCESS ) {
- cout << "error getting task\n";
- return 0;
- }
-
-#if !defined(__LP64__)
- task_basic_info_32 ti;
-#else
- task_basic_info_64 ti;
-#endif
- mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
- if ( ( result = task_info( task , TASK_BASIC_INFO , (task_info_t)&ti, &count ) ) != KERN_SUCCESS ) {
- cout << "error getting task_info: " << result << endl;
- return 0;
- }
- return (int)((double)ti.virtual_size / (1024.0 * 1024 ) );
- }
-
- int ProcessInfo::getResidentSize() {
- task_t result;
-
- mach_port_t task;
-
- if ( ( result = task_for_pid( mach_task_self() , _pid , &task) ) != KERN_SUCCESS ) {
- cout << "error getting task\n";
- return 0;
- }
-
-
-#if !defined(__LP64__)
- task_basic_info_32 ti;
-#else
- task_basic_info_64 ti;
-#endif
- mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
- if ( ( result = task_info( task , TASK_BASIC_INFO , (task_info_t)&ti, &count ) ) != KERN_SUCCESS ) {
- cout << "error getting task_info: " << result << endl;
- return 0;
- }
- return (int)( ti.resident_size / (1024 * 1024 ) );
- }
-
- void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {}
-
- bool ProcessInfo::blockCheckSupported() {
- return true;
- }
-
- bool ProcessInfo::blockInMemory( char * start ) {
- static long pageSize = 0;
- if ( pageSize == 0 ) {
- pageSize = sysconf( _SC_PAGESIZE );
- }
- start = start - ( (unsigned long long)start % pageSize );
- char x = 0;
- if ( mincore( start , 128 , &x ) ) {
- log() << "mincore failed: " << errnoWithDescription() << endl;
- return 1;
- }
- return x & 0x1;
- }
-
-}
diff --git a/util/processinfo_linux2.cpp b/util/processinfo_linux2.cpp
deleted file mode 100644
index e82e2d154aa..00000000000
--- a/util/processinfo_linux2.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-// processinfo_linux2.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "processinfo.h"
-
-#include <iostream>
-#include <stdio.h>
-#include <malloc.h>
-#include <db/jsobj.h>
-#include <unistd.h>
-#include <sys/mman.h>
-
-using namespace std;
-
-#define KLONG long
-#define KLF "l"
-
-namespace mongo {
-
- class LinuxProc {
- public:
- LinuxProc( pid_t pid = getpid() ) {
- char name[128];
- sprintf( name , "/proc/%d/stat" , pid );
-
- FILE * f = fopen( name , "r");
- if ( ! f ) {
- stringstream ss;
- ss << "couldn't open [" << name << "] " << errnoWithDescription();
- string s = ss.str();
- // help the assert# control uasserted( 13538 , s.c_str() );
- msgassertedNoTrace( 13538 , s.c_str() );
- }
- int found = fscanf(f,
- "%d %s %c "
- "%d %d %d %d %d "
- "%lu %lu %lu %lu %lu "
- "%lu %lu %ld %ld " /* utime stime cutime cstime */
- "%ld %ld "
- "%ld "
- "%ld "
- "%lu " /* start_time */
- "%lu "
- "%ld " // rss
- "%lu %"KLF"u %"KLF"u %"KLF"u %"KLF"u %"KLF"u "
- /*
- "%*s %*s %*s %*s "
- "%"KLF"u %*lu %*lu "
- "%d %d "
- "%lu %lu"
- */
-
- ,
-
- &_pid,
- _comm,
- &_state,
- &_ppid, &_pgrp, &_session, &_tty, &_tpgid,
- &_flags, &_min_flt, &_cmin_flt, &_maj_flt, &_cmaj_flt,
- &_utime, &_stime, &_cutime, &_cstime,
- &_priority, &_nice,
- &_alarm,
- &_nlwp,
- &_start_time,
- &_vsize,
- &_rss,
- &_rss_rlim, &_start_code, &_end_code, &_start_stack, &_kstk_esp, &_kstk_eip
-
- /*
- &_wchan,
- &_exit_signal, &_processor,
- &_rtprio, &_sched
- */
- );
- if ( found == 0 ) {
- cout << "system error: reading proc info" << endl;
- }
- fclose( f );
- }
-
- unsigned long getVirtualMemorySize() {
- return _vsize;
- }
-
- unsigned long getResidentSize() {
- return (unsigned long)_rss * 4 * 1024;
- }
-
- int _pid;
- // The process ID.
-
- char _comm[128];
- // The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out.
-
- char _state;
- //One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible
- // disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging.
-
- int _ppid;
- // The PID of the parent.
-
- int _pgrp;
- // The process group ID of the process.
-
- int _session;
- // The session ID of the process.
-
- int _tty;
- // The tty the process uses.
-
- int _tpgid;
- // The process group ID of the process which currently owns the tty that the process is connected to.
-
- unsigned long _flags; // %lu
- // The kernel flags word of the process. For bit meanings, see the PF_* defines in <linux/sched.h>. Details depend on the kernel version.
-
- unsigned long _min_flt; // %lu
- // The number of minor faults the process has made which have not required loading a memory page from disk.
-
- unsigned long _cmin_flt; // %lu
- // The number of minor faults that the process
-
- unsigned long _maj_flt; // %lu
- // The number of major faults the process has made which have required loading a memory page from disk.
-
- unsigned long _cmaj_flt; // %lu
- // The number of major faults that the process
-
- unsigned long _utime; // %lu
- // The number of jiffies that this process has been scheduled in user mode.
-
- unsigned long _stime; // %lu
- // The number of jiffies that this process has been scheduled in kernel mode.
-
- long _cutime; // %ld
- // The number of jiffies that this removed field.
-
- long _cstime; // %ld
-
- long _priority;
- long _nice;
-
- long _nlwp; // %ld
- // The time in jiffies before the next SIGALRM is sent to the process due to an interval timer.
-
- unsigned long _alarm;
-
- unsigned long _start_time; // %lu
- // The time in jiffies the process started after system boot.
-
- unsigned long _vsize; // %lu
- // Virtual memory size in bytes.
-
- long _rss; // %ld
- // Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which
- // count towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out
-
- unsigned long _rss_rlim; // %lu
- // Current limit in bytes on the rss of the process (usually 4294967295 on i386).
-
- unsigned long _start_code; // %lu
- // The address above which program text can run.
-
- unsigned long _end_code; // %lu
- // The address below which program text can run.
-
- unsigned long _start_stack; // %lu
- // The address of the start of the stack.
-
- unsigned long _kstk_esp; // %lu
- // The current value of esp (stack pointer), as found in the kernel stack page for the process.
-
- unsigned long _kstk_eip; // %lu
- // The current EIP (instruction pointer).
-
-
-
- };
-
-
- ProcessInfo::ProcessInfo( pid_t pid ) : _pid( pid ) {
- }
-
- ProcessInfo::~ProcessInfo() {
- }
-
- bool ProcessInfo::supported() {
- return true;
- }
-
- int ProcessInfo::getVirtualMemorySize() {
- LinuxProc p(_pid);
- return (int)( p.getVirtualMemorySize() / ( 1024.0 * 1024 ) );
- }
-
- int ProcessInfo::getResidentSize() {
- LinuxProc p(_pid);
- return (int)( p.getResidentSize() / ( 1024.0 * 1024 ) );
- }
-
- void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {
- struct mallinfo malloc_info = mallinfo(); // structure has same name as function that returns it. (see malloc.h)
- info.append("heap_usage_bytes", malloc_info.uordblks);
-
- LinuxProc p(_pid);
- info.append("page_faults", (int)p._maj_flt);
- }
-
- bool ProcessInfo::blockCheckSupported() {
- return true;
- }
-
- bool ProcessInfo::blockInMemory( char * start ) {
- static long pageSize = 0;
- if ( pageSize == 0 ) {
- pageSize = sysconf( _SC_PAGESIZE );
- }
- start = start - ( (unsigned long long)start % pageSize );
- unsigned char x = 0;
- if ( mincore( start , 128 , &x ) ) {
- log() << "mincore failed: " << errnoWithDescription() << endl;
- return 1;
- }
- return x & 0x1;
- }
-
-
-}
diff --git a/util/processinfo_none.cpp b/util/processinfo_none.cpp
deleted file mode 100644
index 7d1e84d377c..00000000000
--- a/util/processinfo_none.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-// processinfo_none.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "processinfo.h"
-
-#include <iostream>
-using namespace std;
-
-namespace mongo {
-
- ProcessInfo::ProcessInfo( pid_t pid ) {
- }
-
- ProcessInfo::~ProcessInfo() {
- }
-
- bool ProcessInfo::supported() {
- return false;
- }
-
- int ProcessInfo::getVirtualMemorySize() {
- return -1;
- }
-
- int ProcessInfo::getResidentSize() {
- return -1;
- }
-
- void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {}
-
- bool ProcessInfo::blockCheckSupported() {
- return false;
- }
-
- bool ProcessInfo::blockInMemory( char * start ) {
- assert(0);
- return true;
- }
-
-}
diff --git a/util/processinfo_win32.cpp b/util/processinfo_win32.cpp
deleted file mode 100644
index fdd88d374ac..00000000000
--- a/util/processinfo_win32.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// processinfo_win32.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "processinfo.h"
-#include <iostream>
-#include <psapi.h>
-#include "../bson/bsonobjbuilder.h"
-using namespace std;
-
-int getpid() {
- return GetCurrentProcessId();
-}
-
-namespace mongo {
-
- int _wconvertmtos( SIZE_T s ) {
- return (int)( s / ( 1024 * 1024 ) );
- }
-
- ProcessInfo::ProcessInfo( pid_t pid ) {
- }
-
- ProcessInfo::~ProcessInfo() {
- }
-
- bool ProcessInfo::supported() {
- return true;
- }
-
- int ProcessInfo::getVirtualMemorySize() {
- MEMORYSTATUSEX mse;
- mse.dwLength = sizeof(mse);
- assert( GlobalMemoryStatusEx( &mse ) );
- DWORDLONG x = (mse.ullTotalVirtual - mse.ullAvailVirtual) / (1024 * 1024) ;
- assert( x <= 0x7fffffff );
- return (int) x;
- }
-
- int ProcessInfo::getResidentSize() {
- PROCESS_MEMORY_COUNTERS pmc;
- assert( GetProcessMemoryInfo( GetCurrentProcess() , &pmc, sizeof(pmc) ) );
- return _wconvertmtos( pmc.WorkingSetSize );
- }
-
- void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {
- MEMORYSTATUSEX mse;
- mse.dwLength = sizeof(mse);
- PROCESS_MEMORY_COUNTERS pmc;
- if( GetProcessMemoryInfo( GetCurrentProcess() , &pmc, sizeof(pmc) ) ) {
- info.append("page_faults", static_cast<int>(pmc.PageFaultCount));
- info.append("usagePageFileMB", static_cast<int>(pmc.PagefileUsage / 1024 / 1024));
- }
- if( GlobalMemoryStatusEx( &mse ) ) {
- info.append("totalPageFileMB", static_cast<int>(mse.ullTotalPageFile / 1024 / 1024));
- info.append("availPageFileMB", static_cast<int>(mse.ullAvailPageFile / 1024 / 1024));
- info.append("ramMB", static_cast<int>(mse.ullTotalPhys / 1024 / 1024));
- }
- }
-
- bool ProcessInfo::blockCheckSupported() {
- return false;
- }
-
- bool ProcessInfo::blockInMemory( char * start ) {
- assert(0);
- return true;
- }
-
-}
diff --git a/util/queue.h b/util/queue.h
deleted file mode 100644
index 4223bd6c256..00000000000
--- a/util/queue.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// @file queue.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "../pch.h"
-
-#include <queue>
-
-#include "../util/timer.h"
-
-namespace mongo {
-
- /**
- * simple blocking queue
- */
- template<typename T> class BlockingQueue : boost::noncopyable {
- public:
- BlockingQueue() : _lock("BlockingQueue") { }
-
- void push(T const& t) {
- scoped_lock l( _lock );
- _queue.push( t );
- _condition.notify_one();
- }
-
- bool empty() const {
- scoped_lock l( _lock );
- return _queue.empty();
- }
-
- size_t size() const {
- scoped_lock l( _lock );
- return _queue.size();
- }
-
-
- bool tryPop( T & t ) {
- scoped_lock l( _lock );
- if ( _queue.empty() )
- return false;
-
- t = _queue.front();
- _queue.pop();
-
- return true;
- }
-
- T blockingPop() {
-
- scoped_lock l( _lock );
- while( _queue.empty() )
- _condition.wait( l.boost() );
-
- T t = _queue.front();
- _queue.pop();
- return t;
- }
-
-
- /**
- * blocks waiting for an object until maxSecondsToWait passes
- * if got one, return true and set in t
- * otherwise return false and t won't be changed
- */
- bool blockingPop( T& t , int maxSecondsToWait ) {
-
- Timer timer;
-
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += maxSecondsToWait;
-
- scoped_lock l( _lock );
- while( _queue.empty() ) {
- if ( ! _condition.timed_wait( l.boost() , xt ) )
- return false;
- }
-
- t = _queue.front();
- _queue.pop();
- return true;
- }
-
- private:
- std::queue<T> _queue;
-
- mutable mongo::mutex _lock;
- boost::condition _condition;
- };
-
-}
diff --git a/util/ramlog.cpp b/util/ramlog.cpp
deleted file mode 100644
index d7a839a3fff..00000000000
--- a/util/ramlog.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-// ramlog.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "log.h"
-#include "ramlog.h"
-#include "mongoutils/html.h"
-#include "mongoutils/str.h"
-
-namespace mongo {
-
- using namespace mongoutils;
-
- RamLog::RamLog( string name ) : _name(name), _lastWrite(0) {
- h = 0; n = 0;
- for( int i = 0; i < N; i++ )
- lines[i][C-1] = 0;
-
- if ( name.size() ) {
-
- if ( ! _namedLock )
- _namedLock = new mongo::mutex("RamLog::_namedLock");
-
- scoped_lock lk( *_namedLock );
- if ( ! _named )
- _named = new RM();
- (*_named)[name] = this;
- }
-
- }
-
- RamLog::~RamLog() {
-
- }
-
- void RamLog::write(LogLevel ll, const string& str) {
- _lastWrite = time(0);
-
- char *p = lines[(h+n)%N];
-
- unsigned sz = str.size();
- if( sz < C ) {
- if ( str.c_str()[sz-1] == '\n' ) {
- memcpy(p, str.c_str(), sz-1);
- p[sz-1] = 0;
- }
- else
- strcpy(p, str.c_str());
- }
- else {
- memcpy(p, str.c_str(), C-1);
- }
-
- if( n < N ) n++;
- else h = (h+1) % N;
- }
-
- void RamLog::get( vector<const char*>& v) const {
- for( unsigned x=0, i=h; x++ < n; i=(i+1)%N )
- v.push_back(lines[i]);
- }
-
- int RamLog::repeats(const vector<const char *>& v, int i) {
- for( int j = i-1; j >= 0 && j+8 > i; j-- ) {
- if( strcmp(v[i]+20,v[j]+20) == 0 ) {
- for( int x = 1; ; x++ ) {
- if( j+x == i ) return j;
- if( i+x>=(int) v.size() ) return -1;
- if( strcmp(v[i+x]+20,v[j+x]+20) ) return -1;
- }
- return -1;
- }
- }
- return -1;
- }
-
-
- string RamLog::clean(const vector<const char *>& v, int i, string line ) {
- if( line.empty() ) line = v[i];
- if( i > 0 && strncmp(v[i], v[i-1], 11) == 0 )
- return string(" ") + line.substr(11);
- return v[i];
- }
-
- string RamLog::color(string line) {
- string s = str::after(line, "replSet ");
- if( str::startsWith(s, "warning") || startsWith(s, "error") )
- return html::red(line);
- if( str::startsWith(s, "info") ) {
- if( str::endsWith(s, " up\n") )
- return html::green(line);
- else if( str::contains(s, " down ") || str::endsWith(s, " down\n") )
- return html::yellow(line);
- return line; //html::blue(line);
- }
-
- return line;
- }
-
- /* turn http:... into an anchor */
- string RamLog::linkify(const char *s) {
- const char *p = s;
- const char *h = strstr(p, "http://");
- if( h == 0 ) return s;
-
- const char *sp = h + 7;
- while( *sp && *sp != ' ' ) sp++;
-
- string url(h, sp-h);
- stringstream ss;
- ss << string(s, h-s) << "<a href=\"" << url << "\">" << url << "</a>" << sp;
- return ss.str();
- }
-
- void RamLog::toHTML(stringstream& s) {
- vector<const char*> v;
- get( v );
-
- s << "<pre>\n";
- for( int i = 0; i < (int)v.size(); i++ ) {
- assert( strlen(v[i]) > 20 );
- int r = repeats(v, i);
- if( r < 0 ) {
- s << color( linkify( clean(v,i).c_str() ) ) << '\n';
- }
- else {
- stringstream x;
- x << string(v[i], 0, 20);
- int nr = (i-r);
- int last = i+nr-1;
- for( ; r < i ; r++ ) x << '.';
- if( 1 ) {
- stringstream r;
- if( nr == 1 ) r << "repeat last line";
- else r << "repeats last " << nr << " lines; ends " << string(v[last]+4,0,15);
- s << html::a("", r.str(), clean(v,i,x.str()));
- }
- else s << x.str();
- s << '\n';
- i = last;
- }
- }
- s << "</pre>\n";
- }
-
- // ---------------
- // static things
- // ---------------
-
- RamLog* RamLog::get( string name ) {
- if ( ! _named )
- return 0;
-
- scoped_lock lk( *_namedLock );
- RM::iterator i = _named->find( name );
- if ( i == _named->end() )
- return 0;
- return i->second;
- }
-
- void RamLog::getNames( vector<string>& names ) {
- if ( ! _named )
- return;
-
- scoped_lock lk( *_namedLock );
- for ( RM::iterator i=_named->begin(); i!=_named->end(); ++i ) {
- if ( i->second->n )
- names.push_back( i->first );
- }
- }
-
- mongo::mutex* RamLog::_namedLock;
- RamLog::RM* RamLog::_named = 0;
-
- Tee* const warnings = new RamLog("warnings"); // Things put here go in serverStatus
-}
diff --git a/util/ramlog.h b/util/ramlog.h
deleted file mode 100644
index d3d5c8fbb4e..00000000000
--- a/util/ramlog.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// ramlog.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "log.h"
-
-namespace mongo {
-
- class RamLog : public Tee {
- public:
- RamLog( string name );
-
- virtual void write(LogLevel ll, const string& str);
-
- void get( vector<const char*>& v) const;
-
- void toHTML(stringstream& s);
-
- static RamLog* get( string name );
- static void getNames( vector<string>& names );
-
- time_t lastWrite() { return _lastWrite; } // 0 if no writes
-
- protected:
- static int repeats(const vector<const char *>& v, int i);
- static string clean(const vector<const char *>& v, int i, string line="");
- static string color(string line);
-
- /* turn http:... into an anchor */
- static string linkify(const char *s);
-
- private:
- ~RamLog(); // want this private as we want to leak so we can use them till the very end
-
- enum {
- N = 128, // number of links
- C = 256 // max size of line
- };
- char lines[N][C];
- unsigned h; // current position
- unsigned n; // numer of lines stores 0 o N
- string _name;
-
- typedef map<string,RamLog*> RM;
- static mongo::mutex* _namedLock;
- static RM* _named;
- time_t _lastWrite;
- };
-
-}
diff --git a/util/scopeguard.h b/util/scopeguard.h
deleted file mode 100644
index 8ced04f47fc..00000000000
--- a/util/scopeguard.h
+++ /dev/null
@@ -1,432 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The Loki Library
-// Copyright (c) 2000 Andrei Alexandrescu
-// Copyright (c) 2000 Petru Marginean
-// Copyright (c) 2005 Joshua Lehrer
-//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
-// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
-// without express or implied warranty.
-////////////////////////////////////////////////////////////////////////////////
-#ifndef LOKI_SCOPEGUARD_H_
-#define LOKI_SCOPEGUARD_H_
-
-namespace mongo
-{
-
- ////////////////////////////////////////////////////////////////////////////////
- /// \class RefToValue
- ///
- /// Transports a reference as a value
- /// Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuard
- ////////////////////////////////////////////////////////////////////////////////
-
- template <class T>
- class RefToValue
- {
- public:
-
- RefToValue(T& ref) : ref_(ref)
- {}
-
- RefToValue(const RefToValue& rhs) : ref_(rhs.ref_)
- {}
-
- operator T& () const
- {
- return ref_;
- }
-
- private:
- // Disable - not implemented
- RefToValue();
- RefToValue& operator=(const RefToValue&);
-
- T& ref_;
- };
-
-
- ////////////////////////////////////////////////////////////////////////////////
- /// RefToValue creator.
- ////////////////////////////////////////////////////////////////////////////////
-
- template <class T>
- inline RefToValue<T> ByRef(T& t)
- {
- return RefToValue<T>(t);
- }
-
-
-
-
- ////////////////////////////////////////////
- /// ScopeGuard
- /*
- Trivial example for use:
-
- FILE* f = fopen("myfile.txt", "w+");
- if (!f)
- return error;
- ON_BLOCK_EXIT(fclose, f);
-
-
- More complicated example:
-
- ScopeGuard guard = MakeGuard(my_rollback_func, myparam);
- ...
- if (successful) {
- guard.Dismiss();
- return;
- }
- // guard is still active here and will fire at scope exit
- ...
-
-
- */
-
-
- class ScopeGuardImplBase
- {
- ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
-
- protected:
-
- ~ScopeGuardImplBase()
- {}
-
- ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
- : dismissed_(other.dismissed_)
- {
- other.Dismiss();
- }
-
- template <typename J>
- static void SafeExecute(J& j) throw()
- {
- if (!j.dismissed_)
- try
- {
- j.Execute();
- }
- catch(...)
- {}
- }
-
- mutable bool dismissed_;
-
- public:
- ScopeGuardImplBase() throw() : dismissed_(false)
- {}
-
- void Dismiss() const throw()
- {
- dismissed_ = true;
- }
- };
-
- ////////////////////////////////////////////////////////////////
- ///
- /// \typedef typedef const ScopeGuardImplBase& ScopeGuard
- ///
- /// See Andrei's and Petru Marginean's CUJ article
- /// http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm
- ///
- /// Changes to the original code by Joshua Lehrer:
- /// http://www.lehrerfamily.com/scopeguard.html
- ////////////////////////////////////////////////////////////////
-
- typedef const ScopeGuardImplBase& ScopeGuard;
-
- template <typename F>
- class ScopeGuardImpl0 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl0<F> MakeGuard(F fun)
- {
- return ScopeGuardImpl0<F>(fun);
- }
-
- ~ScopeGuardImpl0() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_();
- }
-
- protected:
- ScopeGuardImpl0(F fun) : fun_(fun)
- {}
-
- F fun_;
- };
-
- template <typename F>
- inline ScopeGuardImpl0<F> MakeGuard(F fun)
- {
- return ScopeGuardImpl0<F>::MakeGuard(fun);
- }
-
- template <typename F, typename P1>
- class ScopeGuardImpl1 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
- {
- return ScopeGuardImpl1<F, P1>(fun, p1);
- }
-
- ~ScopeGuardImpl1() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_(p1_);
- }
-
- protected:
- ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1)
- {}
-
- F fun_;
- const P1 p1_;
- };
-
- template <typename F, typename P1>
- inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
- {
- return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
- }
-
- template <typename F, typename P1, typename P2>
- class ScopeGuardImpl2: public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
- {
- return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
- }
-
- ~ScopeGuardImpl2() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_(p1_, p2_);
- }
-
- protected:
- ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2)
- {}
-
- F fun_;
- const P1 p1_;
- const P2 p2_;
- };
-
- template <typename F, typename P1, typename P2>
- inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
- {
- return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
- }
-
- template <typename F, typename P1, typename P2, typename P3>
- class ScopeGuardImpl3 : public ScopeGuardImplBase
- {
- public:
- static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
- {
- return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
- }
-
- ~ScopeGuardImpl3() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- fun_(p1_, p2_, p3_);
- }
-
- protected:
- ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3)
- {}
-
- F fun_;
- const P1 p1_;
- const P2 p2_;
- const P3 p3_;
- };
-
- template <typename F, typename P1, typename P2, typename P3>
- inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
- {
- return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
- }
-
- //************************************************************
-
- template <class Obj, typename MemFun>
- class ObjScopeGuardImpl0 : public ScopeGuardImplBase
- {
- public:
- static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
- {
- return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
- }
-
- ~ObjScopeGuardImpl0() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- (obj_.*memFun_)();
- }
-
- protected:
- ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun)
- {}
-
- Obj& obj_;
- MemFun memFun_;
- };
-
- template <class Obj, typename MemFun>
- inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
- {
- return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
- }
-
- template <typename Ret, class Obj1, class Obj2>
- inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj)
- {
- return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
- }
-
- template <typename Ret, class Obj1, class Obj2>
- inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj)
- {
- return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
- }
-
- template <class Obj, typename MemFun, typename P1>
- class ObjScopeGuardImpl1 : public ScopeGuardImplBase
- {
- public:
- static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
- {
- return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
- }
-
- ~ObjScopeGuardImpl1() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- (obj_.*memFun_)(p1_);
- }
-
- protected:
- ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1)
- {}
-
- Obj& obj_;
- MemFun memFun_;
- const P1 p1_;
- };
-
- template <class Obj, typename MemFun, typename P1>
- inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
- {
- return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
- }
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
- inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 &obj, P1b p1)
- {
- return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
- }
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
- inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 *obj, P1b p1)
- {
- return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
- }
-
- template <class Obj, typename MemFun, typename P1, typename P2>
- class ObjScopeGuardImpl2 : public ScopeGuardImplBase
- {
- public:
- static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
- {
- return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
- }
-
- ~ObjScopeGuardImpl2() throw()
- {
- SafeExecute(*this);
- }
-
- void Execute()
- {
- (obj_.*memFun_)(p1_, p2_);
- }
-
- protected:
- ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2)
- {}
-
- Obj& obj_;
- MemFun memFun_;
- const P1 p1_;
- const P2 p2_;
- };
-
- template <class Obj, typename MemFun, typename P1, typename P2>
- inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
- {
- return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
- }
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
- inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 &obj, P1b p1, P2b p2)
- {
- return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(obj,memFun,p1,p2);
- }
-
- template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
- inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 *obj, P1b p1, P2b p2)
- {
- return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
- }
-
-} // namespace Loki
-
-#define LOKI_CONCATENATE_DIRECT(s1, s2) s1##s2
-#define LOKI_CONCATENATE(s1, s2) LOKI_CONCATENATE_DIRECT(s1, s2)
-#define LOKI_ANONYMOUS_VARIABLE(str) LOKI_CONCATENATE(str, __LINE__)
-
-#ifdef __GNUC__
-#define ON_BLOCK_EXIT ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) __attribute__ ((unused)) = MakeGuard
-#define ON_BLOCK_EXIT_OBJ ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) __attribute__ ((unused)) = MakeObjGuard
-#else
-#define ON_BLOCK_EXIT ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
-#define ON_BLOCK_EXIT_OBJ ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = MakeObjGuard
-#endif
-
-#endif //LOKI_SCOPEGUARD_H_
diff --git a/util/signal_handlers.cpp b/util/signal_handlers.cpp
deleted file mode 100644
index 0e9ec7a9b15..00000000000
--- a/util/signal_handlers.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// signal_handlers.cpp
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
-
-#if !defined(_WIN32) // TODO: windows support
-#include <unistd.h>
-#endif
-
-#if !defined(_WIN32) && !defined(NOEXECINFO)
-#include <execinfo.h>
-#endif
-
-#include "log.h"
-#include "signal_handlers.h"
-
-namespace mongo {
-
- /*
- * WARNING: PLEASE READ BEFORE CHANGING THIS MODULE
- *
- * All code in this module should be singal-friendly. Before adding any system
- * call or other dependency, please make sure the latter still holds.
- *
- */
-
- static int rawWrite( int fd , char* c , int size ) {
-#if !defined(_WIN32)
-
- int toWrite = size;
- int writePos = 0;
- int wrote;
- while ( toWrite > 0 ) {
- wrote = write( fd , &c[writePos] , toWrite );
- if ( wrote < 1 ) break;
- toWrite -= wrote;
- writePos += wrote;
- }
- return writePos;
-
-#else
-
- return -1;
-
-#endif
- }
-
- static int formattedWrite( int fd , const char* format, ... ) {
- const int MAX_ENTRY = 256;
- static char entryBuf[MAX_ENTRY];
-
- va_list ap;
- va_start( ap , format );
- int entrySize = vsnprintf( entryBuf , MAX_ENTRY-1 , format , ap );
- if ( entrySize < 0 ) {
- return -1;
- }
-
- if ( rawWrite( fd , entryBuf , entrySize ) < 0 ) {
- return -1;
- }
-
- return 0;
- }
-
- static void formattedBacktrace( int fd ) {
-
-#if !defined(_WIN32) && !defined(NOEXECINFO)
-
- int numFrames;
- const int MAX_DEPTH = 20;
- void* stackFrames[MAX_DEPTH];
-
- numFrames = backtrace( stackFrames , 20 );
- for ( int i = 0; i < numFrames; i++ ) {
- formattedWrite( fd , "%p " , stackFrames[i] );
- }
- formattedWrite( fd , "\n" );
-
- backtrace_symbols_fd( stackFrames , numFrames , fd );
-
-#else
-
- formattedWrite( fd, "backtracing not implemented for this platform yet\n" );
-
-#endif
-
- }
-
- void printStackAndExit( int signalNum ) {
- int fd = Logstream::getLogDesc();
-
- if ( fd >= 0 ) {
- formattedWrite( fd , "Received signal %d\n" , signalNum );
- formattedWrite( fd , "Backtrace: " );
- formattedBacktrace( fd );
- formattedWrite( fd , "===\n" );
- }
-
- ::exit( EXIT_ABRUPT );
- }
-
-} // namespace mongo
diff --git a/util/signal_handlers.h b/util/signal_handlers.h
deleted file mode 100644
index 9d3a735a723..00000000000
--- a/util/signal_handlers.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// signal_handlers.h
-
-/**
-* Copyright (C) 2010 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "../pch.h"
-
-namespace mongo {
-
- /**
- * Obtains the log file handler and writes the current thread's stack trace to
- * it. This call issues an exit(). The function can safely be called from within a
- * signal handler.
- *
- * @param signal that this hadler is called for
- */
- void printStackAndExit( int signalNum );
-
-} // namespace mongo
diff --git a/util/stringutils.cpp b/util/stringutils.cpp
deleted file mode 100644
index 229f57bb3cb..00000000000
--- a/util/stringutils.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// stringutils.cpp
-
-/**
-* Copyright (C) 2008 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "pch.h"
-
-namespace mongo {
-
- void splitStringDelim( const string& str , vector<string>* res , char delim ) {
- if ( str.empty() )
- return;
-
- size_t beg = 0;
- size_t pos = str.find( delim );
- while ( pos != string::npos ) {
- res->push_back( str.substr( beg, pos - beg) );
- beg = ++pos;
- pos = str.find( delim, beg );
- }
- res->push_back( str.substr( beg ) );
- }
-
- void joinStringDelim( const vector<string>& strs , string* res , char delim ) {
- for ( vector<string>::const_iterator it = strs.begin(); it != strs.end(); ++it ) {
- if ( it !=strs.begin() ) res->push_back( delim );
- res->append( *it );
- }
- }
-
-} // namespace mongo
diff --git a/util/stringutils.h b/util/stringutils.h
deleted file mode 100644
index 93598aa520b..00000000000
--- a/util/stringutils.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// stringutils.h
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
-
- // see also mongoutils/str.h - perhaps move these there?
- // see also text.h
-
- void splitStringDelim( const string& str , vector<string>* res , char delim );
-
- void joinStringDelim( const vector<string>& strs , string* res , char delim );
-
- inline string tolowerString( const string& input ) {
- string::size_type sz = input.size();
-
- boost::scoped_array<char> line(new char[sz+1]);
- char * copy = line.get();
-
- for ( string::size_type i=0; i<sz; i++ ) {
- char c = input[i];
- copy[i] = (char)tolower( (int)c );
- }
- copy[sz] = 0;
- return string(copy);
- }
-
- /**
- * Non numeric characters are compared lexicographically; numeric substrings
- * are compared numerically; dots separate ordered comparable subunits.
- * For convenience, character 255 is greater than anything else.
- */
- inline int lexNumCmp( const char *s1, const char *s2 ) {
- //cout << "START : " << s1 << "\t" << s2 << endl;
-
- bool startWord = true;
-
- while( *s1 && *s2 ) {
-
- bool d1 = ( *s1 == '.' );
- bool d2 = ( *s2 == '.' );
- if ( d1 && !d2 )
- return -1;
- if ( d2 && !d1 )
- return 1;
- if ( d1 && d2 ) {
- ++s1; ++s2;
- startWord = true;
- continue;
- }
-
- bool p1 = ( *s1 == (char)255 );
- bool p2 = ( *s2 == (char)255 );
- //cout << "\t\t " << p1 << "\t" << p2 << endl;
- if ( p1 && !p2 )
- return 1;
- if ( p2 && !p1 )
- return -1;
-
- bool n1 = isNumber( *s1 );
- bool n2 = isNumber( *s2 );
-
- if ( n1 && n2 ) {
- // get rid of leading 0s
- if ( startWord ) {
- while ( *s1 == '0' ) s1++;
- while ( *s2 == '0' ) s2++;
- }
-
- char * e1 = (char*)s1;
- char * e2 = (char*)s2;
-
- // find length
- // if end of string, will break immediately ('\0')
- while ( isNumber (*e1) ) e1++;
- while ( isNumber (*e2) ) e2++;
-
- int len1 = (int)(e1-s1);
- int len2 = (int)(e2-s2);
-
- int result;
- // if one is longer than the other, return
- if ( len1 > len2 ) {
- return 1;
- }
- else if ( len2 > len1 ) {
- return -1;
- }
- // if the lengths are equal, just strcmp
- else if ( (result = strncmp(s1, s2, len1)) != 0 ) {
- return result;
- }
-
- // otherwise, the numbers are equal
- s1 = e1;
- s2 = e2;
- startWord = false;
- continue;
- }
-
- if ( n1 )
- return 1;
-
- if ( n2 )
- return -1;
-
- if ( *s1 > *s2 )
- return 1;
-
- if ( *s2 > *s1 )
- return -1;
-
- s1++; s2++;
- startWord = false;
- }
-
- if ( *s1 )
- return 1;
- if ( *s2 )
- return -1;
- return 0;
- }
-
-} // namespace mongo
diff --git a/util/text.cpp b/util/text.cpp
deleted file mode 100644
index 51a2556afdc..00000000000
--- a/util/text.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// text.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "text.h"
-#include "unittest.h"
-
-namespace mongo {
-
- inline int leadingOnes(unsigned char c) {
- if (c < 0x80) return 0;
- static const char _leadingOnes[128] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 - 0x8F
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 0x99
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xA0 - 0xA9
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xB0 - 0xB9
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xC0 - 0xC9
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xD0 - 0xD9
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE0 - 0xE9
- 4, 4, 4, 4, 4, 4, 4, 4, // 0xF0 - 0xF7
- 5, 5, 5, 5, // 0xF8 - 0xFB
- 6, 6, // 0xFC - 0xFD
- 7, // 0xFE
- 8, // 0xFF
- };
- return _leadingOnes[c & 0x7f];
-
- }
-
- bool isValidUTF8(const char *s) {
- int left = 0; // how many bytes are left in the current codepoint
- while (*s) {
- const unsigned char c = (unsigned char) *(s++);
- const int ones = leadingOnes(c);
- if (left) {
- if (ones != 1) return false; // should be a continuation byte
- left--;
- }
- else {
- if (ones == 0) continue; // ASCII byte
- if (ones == 1) return false; // unexpected continuation byte
- if (c > 0xF4) return false; // codepoint too large (< 0x10FFFF)
- if (c == 0xC0 || c == 0xC1) return false; // codepoints <= 0x7F shouldn't be 2 bytes
-
- // still valid
- left = ones-1;
- }
- }
- if (left!=0) return false; // string ended mid-codepoint
- return true;
- }
-
-#if defined(_WIN32)
-
- std::string toUtf8String(const std::wstring& wide) {
- if (wide.size() > boost::integer_traits<int>::const_max)
- throw std::length_error(
- "Wide string cannot be more than INT_MAX characters long.");
- if (wide.size() == 0)
- return "";
-
- // Calculate necessary buffer size
- int len = ::WideCharToMultiByte(
- CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()),
- NULL, 0, NULL, NULL);
-
- // Perform actual conversion
- if (len > 0) {
- std::vector<char> buffer(len);
- len = ::WideCharToMultiByte(
- CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()),
- &buffer[0], static_cast<int>(buffer.size()), NULL, NULL);
- if (len > 0) {
- assert(len == static_cast<int>(buffer.size()));
- return std::string(&buffer[0], buffer.size());
- }
- }
-
- throw boost::system::system_error(
- ::GetLastError(), boost::system::system_category);
- }
-
-#if defined(_UNICODE)
- std::wstring toWideString(const char *s) {
- std::basic_ostringstream<TCHAR> buf;
- buf << s;
- return buf.str();
- }
-#endif
-
-#endif
-
- struct TextUnitTest : public UnitTest {
- void run() {
- assert( parseLL("123") == 123 );
- assert( parseLL("-123000000000") == -123000000000LL );
- }
- } textUnitTest;
-
-}
-
diff --git a/util/text.h b/util/text.h
deleted file mode 100644
index fc2da214097..00000000000
--- a/util/text.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// text.h
-/*
- * Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
-
- class StringSplitter {
- public:
- /** @param big the string to be split
- @param splitter the delimiter
- */
- StringSplitter( const char * big , const char * splitter )
- : _big( big ) , _splitter( splitter ) {
- }
-
- /** @return true if more to be taken via next() */
- bool more() {
- return _big[0];
- }
-
- /** get next split string fragment */
- string next() {
- const char * foo = strstr( _big , _splitter );
- if ( foo ) {
- string s( _big , foo - _big );
- _big = foo + 1;
- while ( *_big && strstr( _big , _splitter ) == _big )
- _big++;
- return s;
- }
-
- string s = _big;
- _big += strlen( _big );
- return s;
- }
-
- void split( vector<string>& l ) {
- while ( more() ) {
- l.push_back( next() );
- }
- }
-
- vector<string> split() {
- vector<string> l;
- split( l );
- return l;
- }
-
- static vector<string> split( const string& big , const string& splitter ) {
- StringSplitter ss( big.c_str() , splitter.c_str() );
- return ss.split();
- }
-
- static string join( vector<string>& l , const string& split ) {
- stringstream ss;
- for ( unsigned i=0; i<l.size(); i++ ) {
- if ( i > 0 )
- ss << split;
- ss << l[i];
- }
- return ss.str();
- }
-
- private:
- const char * _big;
- const char * _splitter;
- };
-
- /* This doesn't defend against ALL bad UTF8, but it will guarantee that the
- * string can be converted to sequence of codepoints. However, it doesn't
- * guarantee that the codepoints are valid.
- */
- bool isValidUTF8(const char *s);
- inline bool isValidUTF8(string s) { return isValidUTF8(s.c_str()); }
-
-#if defined(_WIN32)
-
- std::string toUtf8String(const std::wstring& wide);
-
- std::wstring toWideString(const char *s);
-
- /* like toWideString but UNICODE macro sensitive */
-# if !defined(_UNICODE)
-#error temp error
- inline std::string toNativeString(const char *s) { return s; }
-# else
- inline std::wstring toNativeString(const char *s) { return toWideString(s); }
-# endif
-
-#endif
-
- // expect that n contains a base ten number and nothing else after it
- // NOTE win version hasn't been tested directly
- inline long long parseLL( const char *n ) {
- long long ret;
- uassert( 13307, "cannot convert empty string to long long", *n != 0 );
-#if !defined(_WIN32)
- char *endPtr = 0;
- errno = 0;
- ret = strtoll( n, &endPtr, 10 );
- uassert( 13305, "could not convert string to long long", *endPtr == 0 && errno == 0 );
-#elif _MSC_VER>=1600 // 1600 is VS2k10 1500 is VS2k8
- size_t endLen = 0;
- try {
- ret = stoll( n, &endLen, 10 );
- }
- catch ( ... ) {
- endLen = 0;
- }
- uassert( 13306, "could not convert string to long long", endLen != 0 && n[ endLen ] == 0 );
-#else // stoll() wasn't introduced until VS 2010.
- char* endPtr = 0;
- ret = _strtoi64( n, &endPtr, 10 );
- uassert( 13310, "could not convert string to long long", (*endPtr == 0) && (ret != _I64_MAX) && (ret != _I64_MIN) );
-#endif // !defined(_WIN32)
- return ret;
- }
-}
diff --git a/util/time_support.h b/util/time_support.h
deleted file mode 100644
index ca17807ec96..00000000000
--- a/util/time_support.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// @file time_support.h
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdio> // sscanf
-#include <ctime>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/thread/xtime.hpp>
-#undef assert
-#define assert MONGO_assert
-
-namespace mongo {
-
- inline void time_t_to_Struct(time_t t, struct tm * buf , bool local = false ) {
-#if defined(_WIN32)
- if ( local )
- localtime_s( buf , &t );
- else
- gmtime_s(buf, &t);
-#else
- if ( local )
- localtime_r(&t, buf);
- else
- gmtime_r(&t, buf);
-#endif
- }
-
- // uses ISO 8601 dates without trailing Z
- // colonsOk should be false when creating filenames
- inline string terseCurrentTime(bool colonsOk=true) {
- struct tm t;
- time_t_to_Struct( time(0) , &t );
-
- const char* fmt = (colonsOk ? "%Y-%m-%dT%H:%M:%S" : "%Y-%m-%dT%H-%M-%S");
- char buf[32];
- assert(strftime(buf, sizeof(buf), fmt, &t) == 19);
- return buf;
- }
-
- inline string timeToISOString(time_t time) {
- struct tm t;
- time_t_to_Struct( time, &t );
-
- const char* fmt = "%Y-%m-%dT%H:%M:%SZ";
- char buf[32];
- assert(strftime(buf, sizeof(buf), fmt, &t) == 20);
- return buf;
- }
-
- inline boost::gregorian::date currentDate() {
- boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
- return now.date();
- }
-
- // parses time of day in "hh:mm" format assuming 'hh' is 00-23
- inline bool toPointInTime( const string& str , boost::posix_time::ptime* timeOfDay ) {
- int hh = 0;
- int mm = 0;
- if ( 2 != sscanf( str.c_str() , "%d:%d" , &hh , &mm ) ) {
- return false;
- }
-
- // verify that time is well formed
- if ( ( hh / 24 ) || ( mm / 60 ) ) {
- return false;
- }
-
- boost::posix_time::ptime res( currentDate() , boost::posix_time::hours( hh ) + boost::posix_time::minutes( mm ) );
- *timeOfDay = res;
- return true;
- }
-
-#define MONGO_asctime _asctime_not_threadsafe_
-#define asctime MONGO_asctime
-#define MONGO_gmtime _gmtime_not_threadsafe_
-#define gmtime MONGO_gmtime
-#define MONGO_localtime _localtime_not_threadsafe_
-#define localtime MONGO_localtime
-#define MONGO_ctime _ctime_is_not_threadsafe_
-#define ctime MONGO_ctime
-
-#if defined(_WIN32)
- inline void sleepsecs(int s) {
- Sleep(s*1000);
- }
- inline void sleepmillis(long long s) {
- assert( s <= 0xffffffff );
- Sleep((DWORD) s);
- }
- inline void sleepmicros(long long s) {
- if ( s <= 0 )
- return;
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += (int)( s / 1000000 );
- xt.nsec += (int)(( s % 1000000 ) * 1000);
- if ( xt.nsec >= 1000000000 ) {
- xt.nsec -= 1000000000;
- xt.sec++;
- }
- boost::thread::sleep(xt);
- }
-#elif defined(__sunos__)
- inline void sleepsecs(int s) {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += s;
- boost::thread::sleep(xt);
- }
- inline void sleepmillis(long long s) {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += (int)( s / 1000 );
- xt.nsec += (int)(( s % 1000 ) * 1000000);
- if ( xt.nsec >= 1000000000 ) {
- xt.nsec -= 1000000000;
- xt.sec++;
- }
- boost::thread::sleep(xt);
- }
- inline void sleepmicros(long long s) {
- if ( s <= 0 )
- return;
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += (int)( s / 1000000 );
- xt.nsec += (int)(( s % 1000000 ) * 1000);
- if ( xt.nsec >= 1000000000 ) {
- xt.nsec -= 1000000000;
- xt.sec++;
- }
- boost::thread::sleep(xt);
- }
-#else
- inline void sleepsecs(int s) {
- struct timespec t;
- t.tv_sec = s;
- t.tv_nsec = 0;
- if ( nanosleep( &t , 0 ) ) {
- cout << "nanosleep failed" << endl;
- }
- }
- inline void sleepmicros(long long s) {
- if ( s <= 0 )
- return;
- struct timespec t;
- t.tv_sec = (int)(s / 1000000);
- t.tv_nsec = 1000 * ( s % 1000000 );
- struct timespec out;
- if ( nanosleep( &t , &out ) ) {
- cout << "nanosleep failed" << endl;
- }
- }
- inline void sleepmillis(long long s) {
- sleepmicros( s * 1000 );
- }
-#endif
-
- extern long long jsTime_virtual_skew;
- extern boost::thread_specific_ptr<long long> jsTime_virtual_thread_skew;
-
- // DO NOT TOUCH except for testing
- inline void jsTimeVirtualSkew( long long skew ){
- jsTime_virtual_skew = skew;
- }
- inline long long getJSTimeVirtualSkew(){
- return jsTime_virtual_skew;
- }
-
- inline void jsTimeVirtualThreadSkew( long long skew ){
- jsTime_virtual_thread_skew.reset(new long long(skew));
- }
- inline long long getJSTimeVirtualThreadSkew(){
- if(jsTime_virtual_thread_skew.get()){
- return *(jsTime_virtual_thread_skew.get());
- }
- else return 0;
- }
-
- /** Date_t is milliseconds since epoch */
- inline Date_t jsTime();
-
- /** warning this will wrap */
- inline unsigned curTimeMicros();
-
- inline unsigned long long curTimeMicros64();
-#ifdef _WIN32 // no gettimeofday on windows
- inline unsigned long long curTimeMillis64() {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- return ((unsigned long long)xt.sec) * 1000 + xt.nsec / 1000000;
- }
- inline Date_t jsTime() {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- unsigned long long t = xt.nsec / 1000000;
- return ((unsigned long long) xt.sec * 1000) + t + getJSTimeVirtualSkew() + getJSTimeVirtualThreadSkew();
- }
- inline unsigned long long curTimeMicros64() {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- unsigned long long t = xt.nsec / 1000;
- return (((unsigned long long) xt.sec) * 1000000) + t;
- }
- inline unsigned curTimeMicros() {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- unsigned t = xt.nsec / 1000;
- unsigned secs = xt.sec % 1024;
- return secs*1000000 + t;
- }
-#else
-# include <sys/time.h>
- inline unsigned long long curTimeMillis64() {
- timeval tv;
- gettimeofday(&tv, NULL);
- return ((unsigned long long)tv.tv_sec) * 1000 + tv.tv_usec / 1000;
- }
- inline Date_t jsTime() {
- timeval tv;
- gettimeofday(&tv, NULL);
- unsigned long long t = tv.tv_usec / 1000;
- return ((unsigned long long) tv.tv_sec * 1000) + t + getJSTimeVirtualSkew() + getJSTimeVirtualThreadSkew();
- }
- inline unsigned long long curTimeMicros64() {
- timeval tv;
- gettimeofday(&tv, NULL);
- return (((unsigned long long) tv.tv_sec) * 1000*1000) + tv.tv_usec;
- }
- inline unsigned curTimeMicros() {
- timeval tv;
- gettimeofday(&tv, NULL);
- unsigned secs = tv.tv_sec % 1024;
- return secs*1000*1000 + tv.tv_usec;
- }
-#endif
-
-} // namespace mongo
diff --git a/util/timer.h b/util/timer.h
deleted file mode 100644
index cbfe859ef5c..00000000000
--- a/util/timer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// @file timer.h
-
-/* Copyright 2010 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "time_support.h"
-
-namespace mongo {
-
- /**
- * simple scoped timer
- */
- class Timer /*copyable*/ {
- public:
- Timer() { reset(); }
- Timer( unsigned long long startMicros ) { old = startMicros; }
- int seconds() const { return (int)(micros() / 1000000); }
- int millis() const { return (int)(micros() / 1000); }
- int minutes() const { return seconds() / 60; }
-
-
- /** gets time interval and resets at the same time. this way we can call curTimeMicros
- once instead of twice if one wanted millis() and then reset().
- @return time in millis
- */
- int millisReset() {
- unsigned long long now = curTimeMicros64();
- int m = (int)((now-old)/1000);
- old = now;
- return m;
- }
-
- // note: dubious that the resolution is as anywhere near as high as ethod name implies!
- unsigned long long micros() const {
- unsigned long long n = curTimeMicros64();
- return n - old;
- }
- unsigned long long micros(unsigned long long & n) const { // returns cur time in addition to timer result
- n = curTimeMicros64();
- return n - old;
- }
-
- unsigned long long startTime() const { return old; }
- void reset() { old = curTimeMicros64(); }
- private:
- unsigned long long old;
- };
-
-#if 1
- class DevTimer {
- public:
- class scoped {
- public:
- scoped(DevTimer& dt) { }
- ~scoped() { }
- };
- DevTimer(string) { }
- ~DevTimer() { }
- };
-#elif defined(_WIN32)
- class DevTimer {
- const string _name;
- public:
- unsigned long long _ticks;
- class scoped {
- DevTimer& _dt;
- unsigned long long _start;
- public:
- scoped(DevTimer& dt) : _dt(dt) {
- LARGE_INTEGER i;
- QueryPerformanceCounter(&i);
- _start = i.QuadPart;
- }
- ~scoped() {
- LARGE_INTEGER i;
- QueryPerformanceCounter(&i);
- _dt._ticks += (i.QuadPart - _start);
- }
- };
- DevTimer(string name) : _name(name), _ticks(0) {
- }
- ~DevTimer() {
- LARGE_INTEGER freq;
- assert( QueryPerformanceFrequency(&freq) );
- cout << "devtimer\t" << _name << '\t' << _ticks*1000.0/freq.QuadPart << "ms" << endl;
- }
- };
-#endif
-
-} // namespace mongo
diff --git a/util/unittest.h b/util/unittest.h
deleted file mode 100644
index 94be444363f..00000000000
--- a/util/unittest.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// unittest.h
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-namespace mongo {
-
- /* The idea here is to let all initialization of global variables (classes inheriting from UnitTest)
- complete before we run the tests -- otherwise order of initilization being arbitrary may mess
- us up. The app's main() function should call runTests().
-
- To define a unit test, inherit from this and implement run. instantiate one object for the new class
- as a global.
-
- These tests are ran on *every* startup of mongod, so they have to be very lightweight. But it is a
- good quick check for a bad build.
- */
- struct UnitTest {
- UnitTest() {
- registerTest(this);
- }
- virtual ~UnitTest() {}
-
- // assert if fails
- virtual void run() = 0;
-
- static bool testsInProgress() { return running; }
- private:
- static vector<UnitTest*> *tests;
- static bool running;
- public:
- static void registerTest(UnitTest *t) {
- if ( tests == 0 )
- tests = new vector<UnitTest*>();
- tests->push_back(t);
- }
-
- static void runTests() {
- running = true;
- for ( vector<UnitTest*>::iterator i = tests->begin(); i != tests->end(); i++ ) {
- (*i)->run();
- }
- running = false;
- }
- };
-
-
-} // namespace mongo
diff --git a/util/util.cpp b/util/util.cpp
deleted file mode 100644
index 4528e300813..00000000000
--- a/util/util.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// @file util.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include "goodies.h"
-#include "unittest.h"
-#include "file_allocator.h"
-#include "optime.h"
-#include "time_support.h"
-#include "mongoutils/str.h"
-
-namespace mongo {
-
- string hexdump(const char *data, unsigned len) {
- assert( len < 1000000 );
- const unsigned char *p = (const unsigned char *) data;
- stringstream ss;
- for( unsigned i = 0; i < 4 && i < len; i++ ) {
- ss << std::hex << setw(2) << setfill('0');
- unsigned n = p[i];
- ss << n;
- ss << ' ';
- }
- string s = ss.str();
- return s;
- }
-
- boost::thread_specific_ptr<string> _threadName;
-
- unsigned _setThreadName( const char * name ) {
- if ( ! name ) name = "NONE";
-
- static unsigned N = 0;
-
- if ( strcmp( name , "conn" ) == 0 ) {
- string* x = _threadName.get();
- if ( x && mongoutils::str::startsWith( *x , "conn" ) ) {
- int n = atoi( x->c_str() + 4 );
- if ( n > 0 )
- return n;
- warning() << "unexpected thread name [" << *x << "] parsed to " << n << endl;
- }
- unsigned n = ++N;
- stringstream ss;
- ss << name << n;
- _threadName.reset( new string( ss.str() ) );
- return n;
- }
-
- _threadName.reset( new string(name) );
- return 0;
- }
-
-#if defined(_WIN32)
-#define MS_VC_EXCEPTION 0x406D1388
-#pragma pack(push,8)
- typedef struct tagTHREADNAME_INFO {
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to name (in user addr space).
- DWORD dwThreadID; // Thread ID (-1=caller thread).
- DWORD dwFlags; // Reserved for future use, must be zero.
- } THREADNAME_INFO;
-#pragma pack(pop)
-
- void setWinThreadName(const char *name) {
- /* is the sleep here necessary???
- Sleep(10);
- */
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = name;
- info.dwThreadID = -1;
- info.dwFlags = 0;
- __try {
- RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- }
- }
-
- unsigned setThreadName(const char *name) {
- unsigned n = _setThreadName( name );
-#if !defined(_DEBUG)
- // naming might be expensive so don't do "conn*" over and over
- if( string("conn") == name )
- return n;
-#endif
- setWinThreadName(name);
- return n;
- }
-
-#else
-
- unsigned setThreadName(const char * name ) {
- return _setThreadName( name );
- }
-
-#endif
-
- string getThreadName() {
- string * s = _threadName.get();
- if ( s )
- return *s;
- return "";
- }
-
- vector<UnitTest*> *UnitTest::tests = 0;
- bool UnitTest::running = false;
-
- const char *default_getcurns() { return ""; }
- const char * (*getcurns)() = default_getcurns;
-
- int logLevel = 0;
- int tlogLevel = 0;
- mongo::mutex Logstream::mutex("Logstream");
- int Logstream::doneSetup = Logstream::magicNumber();
-
- bool isPrime(int n) {
- int z = 2;
- while ( 1 ) {
- if ( z*z > n )
- break;
- if ( n % z == 0 )
- return false;
- z++;
- }
- return true;
- }
-
- int nextPrime(int n) {
- n |= 1; // 2 goes to 3...don't care...
- while ( !isPrime(n) )
- n += 2;
- return n;
- }
-
- struct UtilTest : public UnitTest {
- void run() {
- assert( isPrime(3) );
- assert( isPrime(2) );
- assert( isPrime(13) );
- assert( isPrime(17) );
- assert( !isPrime(9) );
- assert( !isPrime(6) );
- assert( nextPrime(4) == 5 );
- assert( nextPrime(8) == 11 );
-
- assert( endsWith("abcde", "de") );
- assert( !endsWith("abcde", "dasdfasdfashkfde") );
-
- assert( swapEndian(0x01020304) == 0x04030201 );
-
- }
- } utilTest;
-
- OpTime OpTime::last(0, 0);
-
- /* this is a good place to set a breakpoint when debugging, as lots of warning things
- (assert, wassert) call it.
- */
- void sayDbContext(const char *errmsg) {
- if ( errmsg ) {
- problem() << errmsg << endl;
- }
- printStackTrace();
- }
-
- /* note: can't use malloc herein - may be in signal handler.
- logLockless() likely does not comply and should still be fixed todo
- likewise class string?
- */
- void rawOut( const string &s ) {
- if( s.empty() ) return;
-
- char buf[64];
- time_t_to_String( time(0) , buf );
- /* truncate / don't show the year: */
- buf[19] = ' ';
- buf[20] = 0;
-
- Logstream::logLockless(buf);
- Logstream::logLockless(s);
- Logstream::logLockless("\n");
- }
-
- ostream& operator<<( ostream &s, const ThreadSafeString &o ) {
- s << o.toString();
- return s;
- }
-
- bool StaticObserver::_destroyingStatics = false;
-
-} // namespace mongo
diff --git a/util/version.cpp b/util/version.cpp
deleted file mode 100644
index 58e910dc397..00000000000
--- a/util/version.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-// @file version.cpp
-
-/* Copyright 2009 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "pch.h"
-#include <cstdlib>
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <string>
-#include "unittest.h"
-#include "version.h"
-#include "stringutils.h"
-#include "../db/jsobj.h"
-#include "file.h"
-#include "ramlog.h"
-#include "../db/cmdline.h"
-
-namespace mongo {
-
- /* Approved formats for versionString:
- * 1.2.3
- * 1.2.3-pre-
- * 1.2.3-rc4 (up to rc9)
- * 1.2.3-rc4-pre-
- * If you really need to do something else you'll need to fix _versionArray()
- */
- const char versionString[] = "2.0.7";
-
- // See unit test for example outputs
- static BSONArray _versionArray(const char* version){
- // this is inefficient, but cached so it doesn't matter
- BSONArrayBuilder b;
- string curPart;
- const char* c = version;
- int finalPart = 0; // 0 = final release, -100 = pre, -10 to -1 = -10 + X for rcX
- do { //walks versionString including NUL byte
- if (!(*c == '.' || *c == '-' || *c == '\0')){
- curPart += *c;
- continue;
- }
-
- try {
- unsigned num = stringToNum(curPart.c_str());
- b.append((int) num);
- }
- catch (...){ // not a number
- if (curPart.empty()){
- assert(*c == '\0');
- break;
- }
- else if (startsWith(curPart, "rc")){
- finalPart = -10 + stringToNum(curPart.c_str()+2);
- break;
- }
- else if (curPart == "pre"){
- finalPart = -100;
- break;
- }
- }
-
- curPart = "";
- } while (*c++);
-
- b.append(finalPart);
- return b.arr();
- }
-
- const BSONArray versionArray = _versionArray(versionString);
-
- string mongodVersion() {
- stringstream ss;
- ss << "db version v" << versionString << ", pdfile version " << VERSION << "." << VERSION_MINOR;
- return ss.str();
- }
-
-#ifndef _SCONS
- // only works in scons
- const char * gitVersion() { return "not-scons"; }
-#endif
-
- void printGitVersion() { log() << "git version: " << gitVersion() << endl; }
-
-#ifndef _SCONS
-#if defined(_WIN32)
- string sysInfo() {
- stringstream ss;
- ss << "not-scons win";
- ss << " mscver:" << _MSC_FULL_VER << " built:" << __DATE__;
- ss << " boostver:" << BOOST_VERSION;
-#if( !defined(_MT) )
-#error _MT is not defined
-#endif
- ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit";
- return ss.str();
- }
-#else
- string sysInfo() { return ""; }
-#endif
-#endif
-
- void printSysInfo() {
- log() << "build info: " << sysInfo() << endl;
- }
-
-
- static Tee * startupWarningsLog = new RamLog("startupWarnings"); //intentionally leaked
-
- //
- // system warnings
- //
- void show_warnings() {
- // each message adds a leading and a trailing newline
-
- bool warned = false;
- {
- const char * foo = strchr( versionString , '.' ) + 1;
- int bar = atoi( foo );
- if ( ( 2 * ( bar / 2 ) ) != bar ) {
- log() << startupWarningsLog;
- log() << "** NOTE: This is a development version (" << versionString << ") of MongoDB." << startupWarningsLog;
- log() << "** Not recommended for production." << startupWarningsLog;
- warned = true;
- }
- }
-
- if ( sizeof(int*) == 4 ) {
- log() << startupWarningsLog;
- log() << "** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data" << startupWarningsLog;
- log() << "** see http://blog.mongodb.org/post/137788967/32-bit-limitations" << startupWarningsLog;
- log() << "** with --journal, the limit is lower" << startupWarningsLog;
- warned = true;
- }
-
-#ifdef __linux__
- if (boost::filesystem::exists("/proc/vz") && !boost::filesystem::exists("/proc/bc")) {
- log() << startupWarningsLog;
- log() << "** WARNING: You are running in OpenVZ. This is known to be broken!!!" << startupWarningsLog;
- warned = true;
- }
-
- if (boost::filesystem::exists("/sys/devices/system/node/node1")){
- // We are on a box with a NUMA enabled kernel and more than 1 numa node (they start at node0)
- // Now we look at the first line of /proc/self/numa_maps
- //
- // Bad example:
- // $ cat /proc/self/numa_maps
- // 00400000 default file=/bin/cat mapped=6 N4=6
- //
- // Good example:
- // $ numactl --interleave=all cat /proc/self/numa_maps
- // 00400000 interleave:0-7 file=/bin/cat mapped=6 N4=6
-
- File f;
- f.open("/proc/self/numa_maps", /*read_only*/true);
- if ( f.is_open() && ! f.bad() ) {
- char line[100]; //we only need the first line
- assert( read(f.fd, line, sizeof(line)) <= 100 );
-
- // just in case...
- line[98] = ' ';
- line[99] = '\0';
-
- // skip over pointer
- const char* space = strchr(line, ' ');
-
- if ( ! space ) {
- log() << startupWarningsLog;
- log() << "** WARNING: cannot parse numa_maps" << startupWarningsLog;
- warned = true;
- }
- else if ( ! startsWith(space+1, "interleave") ) {
- log() << startupWarningsLog;
- log() << "** WARNING: You are running on a NUMA machine." << startupWarningsLog;
- log() << "** We suggest launching mongod like this to avoid performance problems:" << startupWarningsLog;
- log() << "** numactl --interleave=all mongod [other options]" << startupWarningsLog;
- warned = true;
- }
- }
- }
-
- if (cmdLine.dur){
- fstream f ("/proc/sys/vm/overcommit_memory", ios_base::in);
- unsigned val;
- f >> val;
-
- if (val == 2) {
- log() << startupWarningsLog;
- log() << "** WARNING: /proc/sys/vm/overcommit_memory is " << val << startupWarningsLog;
- log() << "** Journaling works best with it set to 0 or 1" << startupWarningsLog;
- }
- }
-
- if (boost::filesystem::exists("/proc/sys/vm/zone_reclaim_mode")){
- fstream f ("/proc/sys/vm/zone_reclaim_mode", ios_base::in);
- unsigned val;
- f >> val;
-
- if (val != 0) {
- log() << startupWarningsLog;
- log() << "** WARNING: /proc/sys/vm/zone_reclaim_mode is " << val << startupWarningsLog;
- log() << "** We suggest setting it to 0" << startupWarningsLog;
- log() << "** http://www.kernel.org/doc/Documentation/sysctl/vm.txt" << startupWarningsLog;
- }
- }
-#endif
-
- if (warned) {
- log() << startupWarningsLog;
- }
- }
-
- int versionCmp(StringData rhs, StringData lhs) {
- if (strcmp(rhs.data(),lhs.data()) == 0)
- return 0;
-
- // handle "1.2.3-" and "1.2.3-pre"
- if (rhs.size() < lhs.size()) {
- if (strncmp(rhs.data(), lhs.data(), rhs.size()) == 0 && lhs.data()[rhs.size()] == '-')
- return +1;
- }
- else if (rhs.size() > lhs.size()) {
- if (strncmp(rhs.data(), lhs.data(), lhs.size()) == 0 && rhs.data()[lhs.size()] == '-')
- return -1;
- }
-
- return lexNumCmp(rhs.data(), lhs.data());
- }
-
- class VersionCmpTest : public UnitTest {
- public:
- void run() {
- assert( versionCmp("1.2.3", "1.2.3") == 0 );
- assert( versionCmp("1.2.3", "1.2.4") < 0 );
- assert( versionCmp("1.2.3", "1.2.20") < 0 );
- assert( versionCmp("1.2.3", "1.20.3") < 0 );
- assert( versionCmp("2.2.3", "10.2.3") < 0 );
- assert( versionCmp("1.2.3", "1.2.3-") > 0 );
- assert( versionCmp("1.2.3", "1.2.3-pre") > 0 );
- assert( versionCmp("1.2.3", "1.2.4-") < 0 );
- assert( versionCmp("1.2.3-", "1.2.3") < 0 );
- assert( versionCmp("1.2.3-pre", "1.2.3") < 0 );
-
- log(1) << "versionCmpTest passed" << endl;
- }
- } versionCmpTest;
-
- class VersionArrayTest : public UnitTest {
- public:
- void run() {
- assert( _versionArray("1.2.3") == BSON_ARRAY(1 << 2 << 3 << 0) );
- assert( _versionArray("1.2.0") == BSON_ARRAY(1 << 2 << 0 << 0) );
- assert( _versionArray("2.0.0") == BSON_ARRAY(2 << 0 << 0 << 0) );
-
- assert( _versionArray("1.2.3-pre-") == BSON_ARRAY(1 << 2 << 3 << -100) );
- assert( _versionArray("1.2.0-pre-") == BSON_ARRAY(1 << 2 << 0 << -100) );
- assert( _versionArray("2.0.0-pre-") == BSON_ARRAY(2 << 0 << 0 << -100) );
-
- assert( _versionArray("1.2.3-rc0") == BSON_ARRAY(1 << 2 << 3 << -10) );
- assert( _versionArray("1.2.0-rc1") == BSON_ARRAY(1 << 2 << 0 << -9) );
- assert( _versionArray("2.0.0-rc2") == BSON_ARRAY(2 << 0 << 0 << -8) );
-
- // Note that the pre of an rc is the same as the rc itself
- assert( _versionArray("1.2.3-rc3-pre-") == BSON_ARRAY(1 << 2 << 3 << -7) );
- assert( _versionArray("1.2.0-rc4-pre-") == BSON_ARRAY(1 << 2 << 0 << -6) );
- assert( _versionArray("2.0.0-rc5-pre-") == BSON_ARRAY(2 << 0 << 0 << -5) );
-
- log(1) << "versionArrayTest passed" << endl;
- }
- } versionArrayTest;
-}
diff --git a/util/version.h b/util/version.h
deleted file mode 100644
index 64f8b140fd5..00000000000
--- a/util/version.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef UTIL_VERSION_HEADER
-#define UTIL_VERSION_HEADER
-
-#include <string>
-
-namespace mongo {
- struct BSONArray;
-
- using std::string;
-
- // mongo version
- extern const char versionString[];
- extern const BSONArray versionArray;
- string mongodVersion();
- int versionCmp(StringData rhs, StringData lhs); // like strcmp
-
- const char * gitVersion();
- void printGitVersion();
-
- string sysInfo();
- void printSysInfo();
-
- void show_warnings();
-
-} // namespace mongo
-
-#endif // UTIL_VERSION_HEADER
diff --git a/util/winutil.h b/util/winutil.h
deleted file mode 100644
index b69b69a630d..00000000000
--- a/util/winutil.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// @file winutil.cpp : Windows related utility functions
-//
-// /**
-// * Copyright (C) 2008 10gen Inc.
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU Affero General Public License, version 3,
-// * as published by the Free Software Foundation.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU Affero General Public License for more details.
-// *
-// * You should have received a copy of the GNU Affero General Public License
-// * along with this program. If not, see <http://www.gnu.org/licenses/>.
-// */
-//
-// #include "pch.h"
-
-#pragma once
-
-#if defined(_WIN32)
-#include <windows.h>
-#include "text.h"
-
-namespace mongo {
-
- inline string GetWinErrMsg(DWORD err) {
- LPTSTR errMsg;
- ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, (LPTSTR)&errMsg, 0, NULL );
- std::string errMsgStr = toUtf8String( errMsg );
- ::LocalFree( errMsg );
- // FormatMessage() appends a newline to the end of error messages, we trim it because endl flushes the buffer.
- errMsgStr = errMsgStr.erase( errMsgStr.length() - 2 );
- std::ostringstream output;
- output << errMsgStr << " (" << err << ")";
-
- return output.str();
- }
-}
-
-#endif
-