예제 #1
0
	void ScriptSystem::getClassList(const char* prefix, bool sort, StringSeq& result) const {
		ClassInfoDict::const_iterator it = m_classInfoReg.begin();
		size_t prefixlen = 0;
		
		if (prefix) {
			prefixlen = strlen(prefix);
		}

		for (; it != m_classInfoReg.end(); ++it) {
			ClassInfo* ci = it->second;
			if (prefixlen) {
				if (strncmp(prefix, ci->m_className.c_str(), prefixlen) != 0) {
					continue;
				}

				result.push_back(ci->m_className.c_str() + prefixlen);
			} else {
				result.push_back(ci->m_className);
			}
		}

		if (sort) {
			std::sort(result.begin(), result.end(), std::less<String>());
		}
	}
예제 #2
0
int main(int argc, char* argv[])
{
    CoInitializeEx(NULL, 0);

    Ice::InitializationData id = InitializationData();
    id.properties = Ice::createProperties();
    id.properties->load("config.server");
    id.logger = new MyLoggerI();
    Ice::initialize(argc, argv, id);

    SyncService svc;
    int status = EXIT_FAILURE;

#ifdef _WIN32
    status = svc.main(argc, argv, id);
#else
    //
    // For UNIX, force --nochdir option, so the service isn't started
    // with / as the working directory. That way, if the data
    // directory is specified as a relative path, we don't
    // misinterpret that path.
    //
    StringSeq args;
    args.push_back(argv[0]);
    args.push_back("--nochdir");
    for(int i = 1; i < argc; ++i)
    {
        args.push_back(argv[i]);
    }
    status = svc.main(args);
#endif

    return status;
}
예제 #3
0
bool
Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps)
{
    static const string suffixes[] = 
    { 
        "AdapterId",
        "Endpoints",
        "Locator",
        "PublishedEndpoints",
        "RegisterProcess",
        "ReplicaGroupId",
        "Router",
        "ThreadPerConnection",
        "ThreadPerConnection.StackSize",
        "ThreadPool.Size",
        "ThreadPool.SizeMax",
        "ThreadPool.SizeWarn",
        "ThreadPool.StackSize"
    };

    //
    // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc
    //
    bool addUnknown = true;
    string prefix = _name + ".";
    for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i)
    {
        string icePrefix = string(*i) + ".";
        if(prefix.find(icePrefix) == 0)
        {
            addUnknown = false;
            break;
        }
    }

    bool noProps = true;
    PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix);
    PropertyDict::const_iterator p;
    for(p = props.begin(); p != props.end(); ++p)
    {
        bool valid = false;
        for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i)
        {
            string prop = prefix + suffixes[i];
            if(p->first == prop)
            {
                noProps = false;
                valid = true;
                break;
            }
        }

        if(!valid && addUnknown)
        {
            unknownProps.push_back(p->first);
        }
    }

    return noProps;
}
예제 #4
0
StringSeq golem::data::HandlerTrajectory::getProfiles() const {
	StringSeq profiles;

	for (auto& k : profileDescMap)
		profiles.push_back(k.first);

	return profiles;
}
예제 #5
0
void
IceInternal::ReferenceFactory::checkForUnknownProperties(const string& prefix)
{
    static const string suffixes[] =
    {
        "EndpointSelection",
        "ConnectionCached",
        "PreferSecure",
        "LocatorCacheTimeout",
        "InvocationTimeout",
        "Locator",
        "Router",
        "CollocationOptimized",
        "Context.*"
    };

    //
    // Do not warn about unknown properties list if Ice prefix, ie Ice, Glacier2, etc
    //
    for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i)
    {
        if(prefix.find(*i) == 0)
        {
            return;
        }
    }

    StringSeq unknownProps;
    PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix + ".");
    for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p)
    {
        bool valid = false;
        for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i)
        {
            string prop = prefix + "." + suffixes[i];
            if(IceUtilInternal::match(p->first, prop))
            {
                valid = true;
                break;
            }
        }

        if(!valid)
        {
            unknownProps.push_back(p->first);
        }
    }

    if(unknownProps.size())
    {
        Warning out(_instance->initializationData().logger);
        out << "found unknown properties for proxy '" << prefix << "':";
        for(unsigned int i = 0; i < unknownProps.size(); ++i)
        {
            out << "\n    " << unknownProps[i];
        }
    }
}
예제 #6
0
	StringSeq StringUtil::tokenizeSeq(const char* text, char split /*= ' ' */) {
		StringSeq result;

		if (!text || !text[0])
			return result;

		String str;

		const char* token = text;

		for (; ;) {
			/* skip whitespace */
			while (*token && uint_t(*token) <= ' ' || *token == split) {
				token++;
			}

			if (!*token) break;

			str.clear();

			// handle quoted strings
			if (*token == '\"') {
				token++;
				while (*token && *token != '\"') {
					str += *token++;
				}
				result.push_back(str);
				str.clear();
				if (!*token) {
					break;
				} else {
					token++;
					continue;
				}
			}

			do {
				str+=*token; token++;
			} while (*token != 0 && *token != split);
			result.push_back(str);
		}

		return result;
	}
예제 #7
0
StringSeq
Ice::argsToStringSeq(int argc, char* argv[])
{
    StringSeq result;
    for(int i = 0; i < argc; i++)
    {
        result.push_back(argv[i]);
    }
    return result;
}
예제 #8
0
	StringSeq PathUtil::listFileByExts(const String& base, const String& path, const String& exts, uint_t flags) {

		StringSeq strvec;
		FileInfoSeq fileinfos;

		fileinfos = getFileInfos(base, path, exts, flags);
		for (size_t i=0; i<fileinfos.size(); i++) {
			strvec.push_back(fileinfos[i].fullpath);
		}
		return strvec;
	}
예제 #9
0
StringSeq
Ice::PluginManagerI::getPlugins()
{
    IceUtil::Mutex::Lock sync(*this);

    StringSeq names;
    for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p)
    {
        names.push_back(p->name);
    }
    return names;
}
예제 #10
0
StringSeq
Ice::argsToStringSeq(int /*argc*/, wchar_t* argv[])
{
    //
    // Don't need to use a wide string converter argv is expected to
    // come from Windows API.
    //
    const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter();
    StringSeq args;
    for(int i=0; argv[i] != 0; i++)
    {
        args.push_back(IceUtil::wstringToString(argv[i], converter));
    }
    return args;
}
예제 #11
0
bool
Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps)
{
    static const string suffixes[] =
    {
        "ACM",
        "ACM.Close",
        "ACM.Heartbeat",
        "ACM.Timeout",
        "AdapterId",
        "Endpoints",
        "Locator",
        "Locator.EncodingVersion",
        "Locator.EndpointSelection",
        "Locator.ConnectionCached",
        "Locator.PreferSecure",
        "Locator.CollocationOptimized",
        "Locator.Router",
        "MessageSizeMax",
        "PublishedEndpoints",
        "ReplicaGroupId",
        "Router",
        "Router.EncodingVersion",
        "Router.EndpointSelection",
        "Router.ConnectionCached",
        "Router.PreferSecure",
        "Router.CollocationOptimized",
        "Router.Locator",
        "Router.Locator.EndpointSelection",
        "Router.Locator.ConnectionCached",
        "Router.Locator.PreferSecure",
        "Router.Locator.CollocationOptimized",
        "Router.Locator.LocatorCacheTimeout",
        "Router.Locator.InvocationTimeout",
        "Router.LocatorCacheTimeout",
        "Router.InvocationTimeout",
        "ProxyOptions",
        "ThreadPool.Size",
        "ThreadPool.SizeMax",
        "ThreadPool.SizeWarn",
        "ThreadPool.StackSize",
        "ThreadPool.Serialize",
        "ThreadPool.ThreadPriority"
    };

    //
    // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc
    //
    bool addUnknown = true;
    string prefix = _name + ".";
    for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i)
    {
        string icePrefix = string(*i) + ".";
        if(prefix.find(icePrefix) == 0)
        {
            addUnknown = false;
            break;
        }
    }

    bool noProps = true;
    PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix);
    for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p)
    {
        bool valid = false;
        for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i)
        {
            string prop = prefix + suffixes[i];
            if(p->first == prop)
            {
                noProps = false;
                valid = true;
                break;
            }
        }

        if(!valid && addUnknown)
        {
            unknownProps.push_back(p->first);
        }
    }

    return noProps;
}
예제 #12
0
int
Activator::activate(const string& name,
                    const string& exePath,
                    const string& pwdPath,
#ifndef _WIN32
                    uid_t uid,
                    gid_t gid,
#endif
                    const Ice::StringSeq& options,
                    const Ice::StringSeq& envs,
                    const ServerIPtr& server)
{
    IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);

    if(_deactivating)
    {
        throw string("The node is being shutdown.");
    }

    string path = exePath;
    if(path.empty())
    {
        throw string("The server executable path is empty.");
    }

    string pwd = IcePatch2Internal::simplify(pwdPath);
#ifdef _WIN32
    if(!IceUtilInternal::isAbsolutePath(path))
    {
        if(path.find('/') == string::npos)
        {
            //
            // Get the absolute pathname of the executable.
            //
            wchar_t absbuf[_MAX_PATH];
            wchar_t* fPart;
            wstring ext = path.size() <= 4 || path[path.size() - 4] != '.' ? L".exe" : L"";

            //
            // IceGrid doesn't support to use string converters, so don't need to use
            // any string converter in wstringToString conversions.
            //
            if(SearchPathW(NULL, IceUtil::stringToWstring(path).c_str(), ext.c_str(), _MAX_PATH, absbuf, &fPart) == 0)
            {
                if(_traceLevels->activator > 0)
                {
                    Trace out(_traceLevels->logger, _traceLevels->activatorCat);
                    out << "couldn't find `" << path << "' executable.";
                }
                throw string("Couldn't find `" + path + "' executable.");
            }
            path = IceUtil::wstringToString(absbuf);
        }
        else if(!pwd.empty())
        {
            path = pwd + "/" + path;
        }
    }

    //
    // Get the absolute pathname of the working directory.
    //
    // IceGrid doesn't support to use string converters, so
    // don't need to use any string converter in stringToWstring
    // conversions.
    //
    if(!pwd.empty())
    {
        wchar_t absbuf[_MAX_PATH];
        if(_wfullpath(absbuf, IceUtil::stringToWstring(pwd).c_str(), _MAX_PATH) == NULL)
        {
            if(_traceLevels->activator > 0)
            {
                Trace out(_traceLevels->logger, _traceLevels->activatorCat);
                out << "cannot convert `" << pwd << "' into an absolute path";
            }
            throw string("The server working directory path `" + pwd + "' can't be converted into an absolute path.");
        }
        pwd = IceUtil::wstringToString(absbuf);
    }
#endif

    //
    // Setup arguments.
    //
    StringSeq args;
    args.push_back(path);
    args.insert(args.end(), options.begin(), options.end());

    if(_traceLevels->activator > 0)
    {
        Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
        out << "activating server `" << name << "'";
        if(_traceLevels->activator > 1)
        {
            out << "\n";
            out << "path = " << path << "\n";
            if(pwd.empty())
            {
                string cwd;
                if(IceUtilInternal::getcwd(cwd) == 0)
                {
                    out << "pwd = " << cwd << "\n";
                }
            }
            else
            {
                out << "pwd = " << pwd << "\n";
            }
#ifndef _WIN32
            out << "uid/gid = " << uid << "/" << gid << "\n";
#endif
            if(!envs.empty())
            {
                out << "envs = " << toString(envs, ", ") << "\n";
            }
            if(!args.empty())
            {
                out << "args = " << toString(args);
            }
        }
    }

    //
    // Activate and create.
    //
#ifdef _WIN32

    //
    // Compose command line.
    //
    string cmd;
    for(StringSeq::const_iterator p = args.begin(); p != args.end(); ++p)
    {
        if(p != args.begin())
        {
            cmd.push_back(' ');
        }
        //
        // Enclose arguments containing spaces in double quotes.
        //
        if((*p).find(' ') != string::npos)
        {
            cmd.push_back('"');
            cmd.append(*p);
            cmd.push_back('"');
        }
        else
        {
            cmd.append(*p);
        }
    }

    //
    // IceGrid doesn't support to use string converters, so don't need to use
    // any string converter in stringToWstring conversions.
    //
    wstring wpwd = IceUtil::stringToWstring(pwd);
    const wchar_t* dir = !wpwd.empty() ? wpwd.c_str() : NULL;

    //
    // Make a copy of the command line.
    //
    wchar_t* cmdbuf = _wcsdup(IceUtil::stringToWstring(cmd).c_str());

    //
    // Create the environment block for the child process. We start with the environment
    // of this process, and then merge environment variables from the server description.
    // Since Windows is case insensitive wrt environment variables we convert the keys to
    // uppercase to ensure matches are found.
    //
    const wchar_t* env = NULL;
    wstring envbuf;
    if(!envs.empty())
    {
        map<wstring, wstring, UnicodeStringLess> envMap;
        LPVOID parentEnv = GetEnvironmentStringsW();
        const wchar_t* var = reinterpret_cast<const wchar_t*>(parentEnv);
        if(*var == L'=')
        {
            //
            // The environment block may start with some information about the
            // current drive and working directory. This is indicated by a leading
            // '=' character, so we skip to the first '\0' byte.
            //
            while(*var != L'\0')
                var++;
            var++;
        }
        while(*var != L'\0')
        {
            wstring s(var);
            wstring::size_type pos = s.find(L'=');
            if(pos != wstring::npos)
            {
                envMap[s.substr(0, pos)] = s.substr(pos + 1);
            }
            var += s.size();
            var++; // Skip the '\0' byte
        }
        FreeEnvironmentStringsW(static_cast<wchar_t*>(parentEnv));
        for(StringSeq::const_iterator p = envs.begin(); p != envs.end(); ++p)
        {
            //
            // IceGrid doesn't support to use string converters, so don't need to use
            // any string converter in stringToWstring conversions.
            //
            wstring s = IceUtil::stringToWstring(*p);
            wstring::size_type pos = s.find(L'=');
            if(pos != wstring::npos)
            {
                envMap[s.substr(0, pos)] = s.substr(pos + 1);
            }
        }

        for(map<wstring, wstring, UnicodeStringLess>::const_iterator q = envMap.begin(); q != envMap.end(); ++q)
        {
            envbuf.append(q->first);
            envbuf.push_back(L'=');
            envbuf.append(q->second);
            envbuf.push_back(L'\0');
        }
        envbuf.push_back(L'\0');
        env = envbuf.c_str();
    }

    Process process;

    STARTUPINFOW si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));
    BOOL b = CreateProcessW(
        NULL,                     // Executable
        cmdbuf,                   // Command line
        NULL,                     // Process attributes
        NULL,                     // Thread attributes
        FALSE,                    // Do NOT inherit handles
        CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT, // Process creation flags
        (LPVOID)env,              // Process environment
        dir,                      // Current directory
        &si,                      // Startup info
        &pi                       // Process info
    );

    free(cmdbuf);

    if(!b)
    {
        throw IceUtilInternal::lastErrorToString();
    }

    //
    // Caller is responsible for closing handles in PROCESS_INFORMATION. We don't need to
    // keep the thread handle, so we close it now. The process handle will be closed later.
    //
    CloseHandle(pi.hThread);
    process.activator = this;
    process.pid = pi.dwProcessId;
    process.hnd = pi.hProcess;
    process.server = server;
    map<string, Process>::iterator it = _processes.insert(make_pair(name, process)).first;

    Process* pp = &it->second;
    if(!RegisterWaitForSingleObject(&pp->waithnd, pp->hnd, activatorWaitCallback, pp, INFINITE,
                                    WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE))
    {
        throw IceUtilInternal::lastErrorToString();
    }

    //
    // Don't print the following trace, this might interfer with the
    // output of the started process if it fails with an error message.
    //
//     if(_traceLevels->activator > 0)
//     {
//         Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
//         out << "activated server `" << name << "' (pid = " << pi.dwProcessId << ")";
//     }

    return static_cast<Ice::Int>(process.pid);
#else
    int fds[2];
    if(pipe(fds) != 0)
    {
        SyscallException ex(__FILE__, __LINE__);
        ex.error = getSystemErrno();
        throw ex;
    }

    int errorFds[2];
    if(pipe(errorFds) != 0)
    {
        SyscallException ex(__FILE__, __LINE__);
        ex.error = getSystemErrno();
        throw ex;
    }


    //
    // Convert to standard argc/argv.
    //
    IceUtilInternal::ArgVector av(args);
    IceUtilInternal::ArgVector env(envs);

    //
    // Current directory
    //
    const char* pwdCStr = pwd.c_str();

    pid_t pid = fork();
    if(pid == -1)
    {
        SyscallException ex(__FILE__, __LINE__);
        ex.error = getSystemErrno();
        throw ex;
    }

    if(pid == 0) // Child process.
    {
        //
        // Until exec, we can only use async-signal safe functions
        //

        //
        // Unblock signals blocked by IceUtil::CtrlCHandler.
        //
        sigset_t sigs;
        sigemptyset(&sigs);
        sigaddset(&sigs, SIGHUP);
        sigaddset(&sigs, SIGINT);
        sigaddset(&sigs, SIGTERM);
        sigprocmask(SIG_UNBLOCK, &sigs, 0);

        //
        // Change the uid/gid under which the process will run.
        //
        if(setgid(gid) == -1)
        {
            ostringstream os;
            os << gid;
            reportChildError(getSystemErrno(), errorFds[1], "cannot set process group id", os.str().c_str(),
                             _traceLevels);
        }

        errno = 0;
        struct passwd* pw = getpwuid(uid);
        if(!pw)
        {
            if(errno)
            {
                reportChildError(getSystemErrno(), errorFds[1], "cannot read the password database", "",
                                 _traceLevels);
            }
            else
            {
                ostringstream os;
                os << uid;
                reportChildError(getSystemErrno(), errorFds[1], "unknown user uid"  , os.str().c_str(),
                                 _traceLevels);
            }
        }

        //
        // Don't initialize supplementary groups if we are not running as root.
        //
        if(getuid() == 0 && initgroups(pw->pw_name, gid) == -1)
        {
            ostringstream os;
            os << pw->pw_name;
            reportChildError(getSystemErrno(), errorFds[1], "cannot initialize process supplementary group access list for user",
                             os.str().c_str(), _traceLevels);
        }

        if(setuid(uid) == -1)
        {
            ostringstream os;
            os << uid;
            reportChildError(getSystemErrno(), errorFds[1], "cannot set process user id", os.str().c_str(),
                             _traceLevels);
        }

        //
        // Assign a new process group for this process.
        //
        setpgid(0, 0);

        //
        // Close all file descriptors, except for standard input,
        // standard output, standard error, and the write side
        // of the newly created pipe.
        //
        int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
        for(int fd = 3; fd < maxFd; ++fd)
        {
            if(fd != fds[1] && fd != errorFds[1])
            {
                close(fd);
            }
        }

        for(int i = 0; i < env.argc; i++)
        {
            //
            // Each env is leaked on purpose ... see man putenv().
            //
            if(putenv(strdup(env.argv[i])) != 0)
            {
                reportChildError(errno, errorFds[1], "cannot set environment variable",  env.argv[i],
                                 _traceLevels);
            }
        }

        //
        // Change working directory.
        //
        if(strlen(pwdCStr) != 0)
        {
            if(chdir(pwdCStr) == -1)
            {
                reportChildError(errno, errorFds[1], "cannot change working directory to",  pwdCStr,
                                 _traceLevels);
            }
        }

        //
        // Close on exec the error message file descriptor.
        //
        int flags = fcntl(errorFds[1], F_GETFD);
        flags |= 1; // FD_CLOEXEC
        if(fcntl(errorFds[1], F_SETFD, flags) == -1)
        {
            close(errorFds[1]);
            errorFds[1] = -1;
        }

        if(execvp(av.argv[0], av.argv) == -1)
        {
            if(errorFds[1] != -1)
            {
                reportChildError(errno, errorFds[1], "cannot execute",  av.argv[0], _traceLevels);
            }
            else
            {
                reportChildError(errno, fds[1], "cannot execute",  av.argv[0], _traceLevels);
            }
        }
    }
    else // Parent process.
    {
        close(fds[1]);
        close(errorFds[1]);

        //
        // Read a potential error message over the error message pipe.
        //
        char s[16];
        ssize_t rs;
        string message;
        while((rs = read(errorFds[0], &s, 16)) > 0)
        {
            message.append(s, rs);
        }

        //
        // If an error occured before the exec() we do some cleanup and throw.
        //
        if(!message.empty())
        {
            close(fds[0]);
            close(errorFds[0]);
            waitPid(pid);
            throw message;
        }

        //
        // Otherwise, the exec() was successfull and we don't need the error message
        // pipe anymore.
        //
        close(errorFds[0]);

        Process process;
        process.pid = pid;
        process.pipeFd = fds[0];
        process.server = server;
        _processes.insert(make_pair(name, process));

        int flags = fcntl(process.pipeFd, F_GETFL);
        flags |= O_NONBLOCK;
        fcntl(process.pipeFd, F_SETFL, flags);

        setInterrupt();

    //
    // Don't print the following trace, this might interfere with the
    // output of the started process if it fails with an error message.
    //
//      if(_traceLevels->activator > 0)
//      {
//          Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
//          out << "activated server `" << name << "' (pid = " << pid << ")";
//      }
    }

    return pid;
#endif
}
예제 #13
0
파일: MapDb.cpp 프로젝트: bholl/zeroc-ice
Freeze::MapDb::MapDb(const ConnectionIPtr& connection, 
                     const string& dbName,
                     const string& key,
                     const string& value,
                     const KeyCompareBasePtr& keyCompare,
                     const vector<MapIndexBasePtr>& indices,
                     bool createDb) :
    Db(connection->dbEnv()->getEnv(), 0),
    _communicator(connection->communicator()),
    _dbName(dbName),
    _trace(connection->trace()),
    _keyCompare(keyCompare)
{
    if(_trace >= 1)
    {
        Trace out(_communicator->getLogger(), "Freeze.Map");
        out << "opening Db \"" << _dbName << "\"";
    }

    Catalog catalog(connection, _catalogName);
   
    TransactionPtr tx = connection->currentTransaction();
    bool ownTx = (tx == 0);

    for(;;)
    {
        try
        {
            if(ownTx)
            {
                tx = 0;
                tx = connection->beginTransaction();
            }

            Catalog::iterator ci = catalog.find(_dbName);
        
            if(ci != catalog.end())
            {
                if(ci->second.evictor)
                {
                    throw DatabaseException(__FILE__, __LINE__, _dbName + " is an evictor database");
                }
                
                _key = ci->second.key;
                _value = ci->second.value;
                checkTypes(key, value);
            }
            else
            {
                _key = key;
                _value = value;
            }
    
            set_app_private(this);
            if(_keyCompare->compareEnabled())
            {
                set_bt_compare(&customCompare);
            }
            
            PropertiesPtr properties = _communicator->getProperties();
            string propPrefix = "Freeze.Map." + _dbName + ".";
            
            int btreeMinKey = properties->getPropertyAsInt(propPrefix + "BtreeMinKey");
            if(btreeMinKey > 2)
            {
                if(_trace >= 1)
                {
                    Trace out(_communicator->getLogger(), "Freeze.Map");
                    out << "Setting \"" << _dbName << "\"'s btree minkey to " << btreeMinKey;
                }
                set_bt_minkey(btreeMinKey);
            }
            
            bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0;
            if(checksum)
            {
                if(_trace >= 1)
                {
                    Trace out(_communicator->getLogger(), "Freeze.Map");
                    out << "Turning checksum on for \"" << _dbName << "\"";
                }
                
                set_flags(DB_CHKSUM);
            }
            
            int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize");
            if(pageSize > 0)
            {
                if(_trace >= 1)
                {
                    Trace out(_communicator->getLogger(), "Freeze.Map");
                    out << "Setting \"" << _dbName << "\"'s pagesize to " << pageSize;
                }
                set_pagesize(pageSize);
            }
            

            DbTxn* txn = getTxn(tx);
            
            u_int32_t flags = DB_THREAD;
            if(createDb)
            {
                flags |= DB_CREATE;
            }

            open(txn, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE);
            
            
            StringSeq oldIndices;
            StringSeq newIndices;
            size_t oldSize = 0;
            CatalogIndexList catalogIndexList(connection, _catalogIndexListName);
            
            if(createDb)
            {
                CatalogIndexList::iterator cil = catalogIndexList.find(_dbName);
                if(cil != catalogIndexList.end())
                {
                    oldIndices = cil->second;
                    oldSize = oldIndices.size();
                }
            } 
            
            for(vector<MapIndexBasePtr>::const_iterator p = indices.begin();
                p != indices.end(); ++p)
            {
                const MapIndexBasePtr& indexBase = *p; 
                assert(indexBase->_impl == 0);
                assert(indexBase->_communicator == 0);
                indexBase->_communicator = connection->communicator();
                
                auto_ptr<MapIndexI> indexI;

                try
                {
                    indexI.reset(new MapIndexI(connection, *this, txn, createDb, indexBase));
                }
                catch(const DbDeadlockException&)
                {
                    throw;
                }
                catch(const DbException& dx)
                {
                    string message = "Error while opening index \"" + _dbName +
                        "." + indexBase->name() + "\": " + dx.what();

                    throw DatabaseException(__FILE__, __LINE__, message);
                }
                
#ifndef NDEBUG
                bool inserted = 
#endif
                    _indices.insert(IndexMap::value_type(indexBase->name(), indexI.get())).second;
                assert(inserted);
                
                indexBase->_impl = indexI.release();
                
                if(createDb)
                {
                    newIndices.push_back(indexBase->name());
                    oldIndices.erase(std::remove(oldIndices.begin(), oldIndices.end(), indexBase->name()), oldIndices.end());
                }
            }
            
            if(ci == catalog.end())
            {
                CatalogData catalogData;
                catalogData.evictor = false;
                catalogData.key = key;
                catalogData.value = value;
                catalog.put(Catalog::value_type(_dbName, catalogData));
            }
            
            if(createDb)
            {
                //
                // Remove old indices and write the new ones
                //
                bool indexRemoved = false;

                for(StringSeq::const_iterator q = oldIndices.begin(); q != oldIndices.end(); ++q)
                {
                    const string& index = *q;
                    
                    if(_trace >= 1)
                    {
                        Trace out(_communicator->getLogger(), "Freeze.Map");
                        out << "removing old index \"" << index << "\" on Db \"" << _dbName << "\"";
                    }
                    
                    try
                    {
                        connection->removeMapIndex(_dbName, *q);
                        indexRemoved = true;
                    }
                    catch(const IndexNotFoundException&)
                    {
                        // Ignored
                        
                        if(_trace >= 1)
                        {
                            Trace out(_communicator->getLogger(), "Freeze.Map");
                            out << "index \"" << index << "\" on Db \"" << _dbName << "\" does not exist";
                        }
                    }
                }
                
                if(indexRemoved || oldSize != newIndices.size())
                {
                    if(newIndices.size() == 0)
                    {
                        catalogIndexList.erase(_dbName);
                        if(_trace >= 1)
                        {
                            Trace out(_communicator->getLogger(), "Freeze.Map");
                            out << "Removed catalogIndexList entry for Db \"" << _dbName << "\"";
                        }
                        
                    }
                    else
                    {
                        catalogIndexList.put(CatalogIndexList::value_type(_dbName, newIndices));
                        if(_trace >= 1)
                        {
                            Trace out(_communicator->getLogger(), "Freeze.Map");
                            out << "Updated catalogIndexList entry for Db \"" << _dbName << "\"";
                        }
                    }
                }
            }

            if(ownTx)
            {
                tx->commit();
            }
            break; // for(;;)
        }
        catch(const DbDeadlockException& dx)
        {
            if(ownTx)
            {
                if(connection->deadlockWarning())
                {
                    Warning out(connection->communicator()->getLogger());
                    out << "Deadlock in Freeze::MapDb::MapDb on Map \"" 
                        << _dbName << "\"; retrying ...";
                }

                //
                // Ignored, try again
                //
            }
            else
            {
                throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
            }
        }
        catch(const DbException& dx)
        {
            if(ownTx)
            {
                try
                {
                    tx->rollback();
                }
                catch(...)
                {
                }
            }
                
            string message = "Error while opening Db \"" + _dbName +
                "\": " + dx.what();

            throw DatabaseException(__FILE__, __LINE__, message);
        }
        catch(...)
        {
            if(ownTx && tx != 0)
            {   
                try
                {
                    tx->rollback();
                }
                catch(...)
                {
                }
            }
            throw;
        }
    }
}
예제 #14
0
파일: Calc.cpp 프로젝트: Jonavin/ice
int
main(int argc, char* argv[])

#endif
{
    Ice::StringSeq originalArgs = Ice::argsToStringSeq(argc, argv);
    assert(originalArgs.size() > 0);
    const string appName = originalArgs[0];
    string dataDir;
    StringSeq fileSeq;
    int compress = 1;
    bool verbose;
    bool caseInsensitive;

    IceUtilInternal::Options opts;
    opts.addOpt("h", "help");
    opts.addOpt("v", "version");
    opts.addOpt("z", "compress");
    opts.addOpt("Z", "no-compress");
    opts.addOpt("V", "verbose");
    opts.addOpt("i", "case-insensitive");
    
    vector<string> args;
    try
    {
        args = opts.parse(originalArgs);
    }
    catch(const IceUtilInternal::BadOptException& e)
    {
        cerr << e.reason << endl;
        usage(appName);
        return EXIT_FAILURE;
    }

    if(opts.isSet("help"))
    {
        usage(appName);
        return EXIT_SUCCESS;
    }
    if(opts.isSet("version"))
    {
        cout << ICE_STRING_VERSION << endl;
        return EXIT_SUCCESS;
    }
    bool doCompress = opts.isSet("compress");
    bool dontCompress = opts.isSet("no-compress");
    if(doCompress && dontCompress)
    {
        cerr << appName << ": only one of -z and -Z are mutually exclusive" << endl;
        usage(appName);
        return EXIT_FAILURE;
    }
    if(doCompress)
    {
        compress = 2;
    }
    else if(dontCompress)
    {
        compress = 0;
    }
    verbose = opts.isSet("verbose");
    caseInsensitive = opts.isSet("case-insensitive");

    if(args.empty())
    {
        cerr << appName << ": no data directory specified" << endl;
        usage(appName);
        return EXIT_FAILURE;
    }
    dataDir = simplify(args[0]);

    for(vector<string>::size_type i = 1; i < args.size(); ++i)
    {
        fileSeq.push_back(simplify(args[i]));
    }

    try
    {
        string absDataDir = dataDir;
    
        string cwd;
        if(IceUtilInternal::getcwd(cwd) != 0)
        {
            throw "cannot get the current directory:\n" + IceUtilInternal::lastErrorToString();
        }

        if(!IceUtilInternal::isAbsolutePath(absDataDir))
        {
            absDataDir = simplify(cwd + '/' + absDataDir);
        }
        
        for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p)
        {
            if(!IceUtilInternal::isAbsolutePath(*p))
            {
                *p = cwd + '/' + *p;
            }
        }

        //
        // We must call simplify() here: under Cygwin, any path starting with
        // a double slash simply doesn't work. But, if dataDir is "/", we end
        // up with paths that start with "//" unless we call simplify().
        //
        string absDataDirWithSlash = simplify(absDataDir + '/');

        for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p)
        {
            if(p->compare(0, absDataDirWithSlash.size(), absDataDirWithSlash) != 0)
            {
                throw "`" + *p + "' is not a path in `" + dataDir + "'";
            }
            
            p->erase(0, absDataDirWithSlash.size());
        }
    
        LargeFileInfoSeq infoSeq;
            
        if(fileSeq.empty())
        {
            CalcCB calcCB;
            if(!getFileInfoSeq(absDataDir, compress, verbose ? &calcCB : 0, infoSeq))
            {
                return EXIT_FAILURE;
            }
        }
        else
        {
            loadFileInfoSeq(absDataDir, infoSeq);

            for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p)
            {
                LargeFileInfoSeq partialInfoSeq;

                CalcCB calcCB;
                if(!getFileInfoSeqSubDir(absDataDir, *p, compress, verbose ? &calcCB : 0, partialInfoSeq))
                {
                    return EXIT_FAILURE;
                }

                LargeFileInfoSeq newInfoSeq;
                newInfoSeq.reserve(infoSeq.size());

                set_difference(infoSeq.begin(),
                               infoSeq.end(),
                               partialInfoSeq.begin(),
                               partialInfoSeq.end(),
                               back_inserter(newInfoSeq),
                               FileInfoPathLess());

                infoSeq.swap(newInfoSeq);

                newInfoSeq.clear();
                newInfoSeq.reserve(infoSeq.size() + partialInfoSeq.size());

                set_union(infoSeq.begin(),
                          infoSeq.end(),
                          partialInfoSeq.begin(),
                          partialInfoSeq.end(),
                          back_inserter(newInfoSeq),
                          FileInfoPathLess());

                infoSeq.swap(newInfoSeq);
            }
        }

        if(caseInsensitive)
        {
            LargeFileInfoSeq newInfoSeq = infoSeq;
            sort(newInfoSeq.begin(), newInfoSeq.end(), IFileInfoPathLess());

            string ex;
            LargeFileInfoSeq::iterator p = newInfoSeq.begin();
            while((p = adjacent_find(p, newInfoSeq.end(), IFileInfoPathEqual())) != newInfoSeq.end())
            {
                do
                {
                    ex += '\n' + dataDir + '/' + p->path;
                    ++p;
                }
                while(p < newInfoSeq.end() && IFileInfoPathEqual()(*(p - 1), *p));
            }

            if(!ex.empty())
            {
                ex = "duplicate files:" + ex;
                throw ex;
            }
        }

        saveFileInfoSeq(absDataDir, infoSeq);
    }
    catch(const string& ex)
    {
        cerr << appName << ": " << ex << endl;
        return EXIT_FAILURE;
    }
    catch(const char* ex)
    {
        cerr << appName << ": " << ex << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}