2009-10-12 21:12:16 +02:00
|
|
|
// client.h
|
2009-10-09 20:59:44 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
2009-10-12 21:12:16 +02:00
|
|
|
/* Client represents a connection to the database (the server-side) and corresponds
|
|
|
|
to an open socket (or logical connection if pooling on sockets) from a client.
|
2009-10-09 20:59:44 +02:00
|
|
|
|
|
|
|
todo: switch to asio...this will fit nicely with that.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2009-12-04 15:46:11 +01:00
|
|
|
#include "../stdafx.h"
|
2009-12-03 23:24:22 +01:00
|
|
|
#include "namespace.h"
|
2009-10-09 20:59:44 +02:00
|
|
|
#include "lasterror.h"
|
2009-10-14 21:48:13 +02:00
|
|
|
#include "../util/top.h"
|
2009-10-09 20:59:44 +02:00
|
|
|
|
|
|
|
namespace mongo {
|
|
|
|
|
2009-10-13 22:01:02 +02:00
|
|
|
class AuthenticationInfo;
|
2009-10-14 20:34:38 +02:00
|
|
|
class Database;
|
2009-12-21 19:19:20 +01:00
|
|
|
class CurOp;
|
2009-10-09 20:59:44 +02:00
|
|
|
|
2009-10-15 06:56:51 +02:00
|
|
|
class Client : boost::noncopyable {
|
2009-10-16 21:36:34 +02:00
|
|
|
public:
|
|
|
|
static boost::mutex clientsMutex;
|
|
|
|
static set<Client*> clients; // always be in clientsMutex when manipulating this
|
2009-10-23 17:13:08 +02:00
|
|
|
|
|
|
|
class GodScope {
|
|
|
|
bool _prev;
|
|
|
|
public:
|
|
|
|
GodScope();
|
|
|
|
~GodScope();
|
|
|
|
};
|
|
|
|
|
2009-10-16 21:36:34 +02:00
|
|
|
private:
|
2009-12-21 19:19:20 +01:00
|
|
|
CurOp * const _curOp;
|
2009-10-16 21:36:34 +02:00
|
|
|
Database *_database;
|
2009-10-13 22:01:02 +02:00
|
|
|
Namespace _ns;
|
2009-10-14 20:34:38 +02:00
|
|
|
//NamespaceString _nsstr;
|
2009-10-16 21:36:34 +02:00
|
|
|
bool _shutdown;
|
2009-10-14 16:20:53 +02:00
|
|
|
list<string> _tempCollections;
|
2009-10-16 21:36:34 +02:00
|
|
|
const char *_desc;
|
2009-10-23 05:47:39 +02:00
|
|
|
bool _god;
|
2009-10-09 20:59:44 +02:00
|
|
|
public:
|
|
|
|
AuthenticationInfo *ai;
|
2009-10-14 21:48:13 +02:00
|
|
|
Top top;
|
2009-10-09 20:59:44 +02:00
|
|
|
|
2009-12-08 17:34:57 +01:00
|
|
|
CurOp* curop() { return _curOp; }
|
2009-12-04 23:11:17 +01:00
|
|
|
Database* database() {
|
|
|
|
return _database;
|
|
|
|
}
|
2009-10-13 22:01:02 +02:00
|
|
|
const char *ns() { return _ns.buf; }
|
|
|
|
|
2009-10-14 20:34:38 +02:00
|
|
|
void setns(const char *ns, Database *db) {
|
|
|
|
_database = db;
|
2009-10-13 22:01:02 +02:00
|
|
|
_ns = ns;
|
2009-10-14 20:34:38 +02:00
|
|
|
//_nsstr = ns;
|
2009-10-13 22:01:02 +02:00
|
|
|
}
|
2009-10-14 20:34:38 +02:00
|
|
|
void clearns() { setns("", 0); }
|
2009-10-13 22:01:02 +02:00
|
|
|
|
2009-10-16 21:36:34 +02:00
|
|
|
Client(const char *desc);
|
2009-10-13 22:01:02 +02:00
|
|
|
~Client();
|
2009-10-09 20:59:44 +02:00
|
|
|
|
2009-12-07 21:42:26 +01:00
|
|
|
const char *desc() const { return _desc; }
|
|
|
|
|
2009-10-14 16:20:53 +02:00
|
|
|
void addTempCollection( const string& ns ){
|
|
|
|
_tempCollections.push_back( ns );
|
|
|
|
}
|
|
|
|
|
2009-10-13 22:01:02 +02:00
|
|
|
/* each thread which does db operations has a Client object in TLS.
|
|
|
|
call this when your thread starts.
|
|
|
|
*/
|
2009-10-16 21:36:34 +02:00
|
|
|
static void initThread(const char *desc);
|
2009-10-09 20:59:44 +02:00
|
|
|
|
2009-10-14 16:20:53 +02:00
|
|
|
/*
|
|
|
|
this has to be called as the client goes away, but before thread termination
|
|
|
|
@return true if anything was done
|
|
|
|
*/
|
|
|
|
bool shutdown();
|
2009-10-23 05:47:39 +02:00
|
|
|
|
2009-10-23 17:13:08 +02:00
|
|
|
bool isGod() const { return _god; }
|
2009-10-14 16:20:53 +02:00
|
|
|
};
|
|
|
|
|
2009-10-23 17:13:08 +02:00
|
|
|
/* defined in security.cpp - one day add client.cpp? */
|
2009-10-12 21:12:16 +02:00
|
|
|
extern boost::thread_specific_ptr<Client> currentClient;
|
2009-10-09 20:59:44 +02:00
|
|
|
|
2009-10-13 22:01:02 +02:00
|
|
|
inline Client& cc() {
|
|
|
|
return *currentClient.get();
|
|
|
|
}
|
|
|
|
|
2009-12-02 15:39:17 +01:00
|
|
|
/* each thread which does db operations has a Client object in TLS.
|
|
|
|
call this when your thread starts.
|
|
|
|
*/
|
2009-10-16 21:36:34 +02:00
|
|
|
inline void Client::initThread(const char *desc) {
|
2009-10-12 21:12:16 +02:00
|
|
|
assert( currentClient.get() == 0 );
|
2009-10-16 21:36:34 +02:00
|
|
|
currentClient.reset( new Client(desc) );
|
2009-10-09 20:59:44 +02:00
|
|
|
}
|
2009-10-23 17:13:08 +02:00
|
|
|
|
|
|
|
inline Client::GodScope::GodScope(){
|
|
|
|
_prev = cc()._god;
|
|
|
|
cc()._god = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Client::GodScope::~GodScope(){
|
|
|
|
cc()._god = _prev;
|
|
|
|
}
|
2009-12-03 17:50:09 +01:00
|
|
|
|
2009-12-06 15:41:53 +01:00
|
|
|
/* this unlocks, does NOT upgrade. that works for our current usage */
|
2009-12-03 17:50:09 +01:00
|
|
|
inline void mongolock::releaseAndWriteLock() {
|
2009-12-06 16:06:02 +01:00
|
|
|
if( !_writelock ) {
|
|
|
|
|
2009-12-06 15:41:53 +01:00
|
|
|
#if BOOST_VERSION >= 103500
|
2009-12-06 16:06:02 +01:00
|
|
|
int s = dbMutex.getState();
|
|
|
|
if( s != -1 ) {
|
|
|
|
log() << "error: releaseAndWriteLock() s == " << s << endl;
|
|
|
|
msgasserted( "releaseAndWriteLock: unlock_shared failed, probably recursive" );
|
|
|
|
}
|
2009-12-06 15:41:53 +01:00
|
|
|
#endif
|
|
|
|
|
2009-12-03 17:50:09 +01:00
|
|
|
_writelock = true;
|
|
|
|
dbMutex.unlock_shared();
|
|
|
|
dbMutex.lock();
|
|
|
|
|
|
|
|
/* this is defensive; as we were unlocked for a moment above,
|
|
|
|
the Database object we reference could have been deleted:
|
|
|
|
*/
|
|
|
|
cc().clearns();
|
|
|
|
}
|
|
|
|
}
|
2009-10-23 05:47:39 +02:00
|
|
|
|
2009-10-09 20:59:44 +02:00
|
|
|
};
|
2009-10-23 17:13:08 +02:00
|
|
|
|