int XML_Backing_Store::persist () { FILE* fp = ACE_OS::fopen (this->filename_.c_str (), "w"); if (fp == 0) { ORBSVCS_ERROR ((LM_ERROR, ACE_TEXT ("Couldn't write to file %C\n"), this->filename_.c_str())); return -1; } ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n"); ACE_OS::fprintf (fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG); // Save servers Locator_Repository::SIMap::ENTRY* sientry = 0; Locator_Repository::SIMap::ITERATOR siit (this->servers ()); for (; siit.next (sientry); siit.advance() ) { persist(fp, *sientry->int_id_, "\t"); } // Save Activators Locator_Repository::AIMap::ENTRY* aientry = 0; Locator_Repository::AIMap::ITERATOR aiit (this->activators ()); for (; aiit.next (aientry); aiit.advance ()) { ACE_CString aname = aientry->ext_id_; persist(fp, *aientry->int_id_, "\t"); } ACE_OS::fprintf (fp,"</%s>\n", Locator_XMLHandler::ROOT_TAG); ACE_OS::fclose (fp); return 0; }
static void persistfunction(PersistInfo *pi) { /* perms reftbl ... func */ Closure *cl = clvalue(getobject(pi->L, -1)); lua_checkstack(pi->L, 2); if(cl->c.isC) { /* It's a C function. For now, we aren't going to allow * persistence of C closures, even if the "C proto" is * already in the permanents table. */ lua_pushstring(pi->L, "Attempt to persist a C function"); lua_error(pi->L); } else { /* It's a Lua closure. */ { /* We don't really _NEED_ the number of upvals, * but it'll simplify things a bit */ pi->writer(pi->L, &cl->l.p->nups, sizeof(lu_byte), pi->ud); } /* Persist prototype */ { pushproto(pi->L, cl->l.p); /* perms reftbl ... func proto */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... func */ } /* Persist upvalue values (not the upvalue objects * themselves) */ { int i; for(i=0; i<cl->l.p->nups; i++) { /* perms reftbl ... func */ pushupval(pi->L, cl->l.upvals[i]); /* perms reftbl ... func upval */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... func */ } /* perms reftbl ... func */ } /* Persist function environment */ { lua_getfenv(pi->L, -1); /* perms reftbl ... func fenv */ if(lua_equal(pi->L, -1, LUA_GLOBALSINDEX)) { /* Function has the default fenv */ /* perms reftbl ... func _G */ lua_pop(pi->L, 1); /* perms reftbl ... func */ lua_pushnil(pi->L); /* perms reftbl ... func nil */ } /* perms reftbl ... func fenv/nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... func */ } } }
static void persistproto(PersistInfo *pi) { /* perms reftbl ... proto */ Proto *p = toproto(pi->L, -1); lua_checkstack(pi->L, 2); /* Persist constant refs */ { int i; pi->writer(pi->L, &p->sizek, sizeof(int), pi->ud); for(i=0; i<p->sizek; i++) { LIF(A,pushobject)(pi->L, &p->k[i]); /* perms reftbl ... proto const */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... proto */ } } /* perms reftbl ... proto */ /* serialize inner Proto refs */ { int i; pi->writer(pi->L, &p->sizep, sizeof(int), pi->ud); for(i=0; i<p->sizep; i++) { pushproto(pi->L, p->p[i]); /* perms reftbl ... proto subproto */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... proto */ } } /* perms reftbl ... proto */ /* Serialize code */ { pi->writer(pi->L, &p->sizecode, sizeof(int), pi->ud); pi->writer(pi->L, p->code, sizeof(Instruction) * p->sizecode, pi->ud); } /* Serialize misc values */ { pi->writer(pi->L, &p->nups, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &p->numparams, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &p->is_vararg, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &p->maxstacksize, sizeof(lu_byte), pi->ud); } /* We do not currently persist upvalue names, local variable names, * variable lifetimes, line info, or source code. */ }
void PythonEngine::thread_on_exception(FunctionTask& task, std::exception& e) { auto python_err = dynamic_cast<python_error*>(&e); if (python_err) { python_err->persist(); } Engine::thread_on_exception(task, e); }
void param_t::write( serialization::yaml_oarchive_t& out) const { if( !value().is_empty() && persist()) { out.begin_map(); out << YAML::Key << "id" << YAML::Value << id(); do_write( out); out.end_map(); } }
/* Upvalues are tricky. Here's why. * * A particular upvalue may be either "open", in which case its member v * points into a thread's stack, or "closed" in which case it points to the * upvalue itself. An upvalue is closed under any of the following conditions: * -- The function that initially declared the variable "local" returns * -- The thread in which the closure was created is garbage collected * * To make things wackier, just because a thread is reachable by Lua doesn't * mean it's in our root set. We need to be able to treat an open upvalue * from an unreachable thread as a closed upvalue. * * The solution: * (a) For the purposes of persisting, don't indicate whether an upvalue is * closed or not. * (b) When unpersisting, pretend that all upvalues are closed. * (c) When persisting, persist all open upvalues referenced by a thread * that is persisted, and tag each one with the corresponding stack position * (d) When unpersisting, "reopen" each of these upvalues as the thread is * unpersisted */ static void persistupval(PersistInfo *pi) { /* perms reftbl ... upval */ UpVal *uv = toupval(pi->L, -1); luaA_pushobject(pi->L, uv->v); /* perms reftbl ... upval obj */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... upval */ }
void process( send_to_venue_command_ptr cmd ) { message_ptr evt1( new send_to_venue_event ); message_ptr evt2( new send_to_venue_event ); evt1->data_ = "evt1"; evt2->data_ = "evt2"; cmd->data_ = "cmd"; persist( { evt1, evt2 }, [ cmd ]() { std::cout << "complete: " << cmd->data_ << std::endl; } ); }
static void persisttable(PersistInfo *pi) { /* perms reftbl ... tbl */ lua_checkstack(pi->L, 3); if(persistspecialobject(pi, 1)) { /* perms reftbl ... tbl */ return; } /* perms reftbl ... tbl */ /* First, persist the metatable (if any) */ if(!lua_getmetatable(pi->L, -1)) { lua_pushnil(pi->L); } /* perms reftbl ... tbl mt/nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... tbl */ /* Now, persist all k/v pairs */ lua_pushnil(pi->L); /* perms reftbl ... tbl nil */ while(lua_next(pi->L, -2)) { /* perms reftbl ... tbl k v */ lua_pushvalue(pi->L, -2); /* perms reftbl ... tbl k v k */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... tbl k v */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... tbl k */ } /* perms reftbl ... tbl */ /* Terminate list */ lua_pushnil(pi->L); /* perms reftbl ... tbl nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... tbl */ }
//---------------------------------------------------------------------- // 初期設定ファイルの準備 //---------------------------------------------------------------------- void TaskScheduler::prepareInitialConfiguration() { struct stat buf; if (stat(path.c_str(), &buf) != 0 && (errno == ENOENT || errno == ENOTDIR)){ std::string cmd = "mkdir -p \"`dirname \""; cmd.append(path.c_str()); cmd.append("\"`\""); system(cmd.c_str()); persist(); } }
/* Upvalues are tricky. Here's why. * * A particular upvalue may be either "open", in which case its member v * points into a thread's stack, or "closed" in which case it points to the * upvalue itself. An upvalue is closed under any of the following conditions: * -- The function that initially declared the variable "local" returns * -- The thread in which the closure was created is garbage collected * * To make things wackier, just because a thread is reachable by Lua doesn't * mean it's in our root set. We need to be able to treat an open upvalue * from an unreachable thread as a closed upvalue. * * The solution: * (a) For the purposes of persisting, don't indicate whether an upvalue is * closed or not. * (b) When unpersisting, pretend that all upvalues are closed. * (c) When persisting, persist all open upvalues referenced by a thread * that is persisted, and tag each one with the corresponding stack position * (d) When unpersisting, "reopen" each of these upvalues as the thread is * unpersisted */ static void persistupval(PersistInfo *pi) { /* perms reftbl ... upval */ UpVal *uv = toupval(pi->L, -1); lua_checkstack(pi->L, 1); /* We can't permit the upval to linger around on the stack, as Lua * will bail if its GC finds it. */ lua_pop(pi->L, 1); /* perms reftbl ... */ LIF(A,pushobject)(pi->L, uv->v); /* perms reftbl ... obj */ persist(pi); /* perms reftbl ... obj */ }
void LearningKernel::train(cv::Mat trainingSet, int layout, cv::Mat response) { if ( layout != cv::ml::COL_SAMPLE && layout != cv::ml::ROW_SAMPLE ) { std::cout << "training set layout " << layout << " is invalid.\n"; return; } initRandomTrees(); std::cout << "train -> begin.\n"; m_pTrees->clear(); m_pTrees->train(trainingSet, layout, response); persist(); std::cout << "train -> complete.\n"; //std::cout << "yay!! not crashing anymore!!" << "\n"; }
void CBrowserView::OnFileSaveAs() { nsCString fileName; GetBrowserWindowTitle(fileName); // Suggest the window title as the filename char *lpszFilter = "Web Page, HTML Only (*.htm;*.html)|*.htm;*.html|" "Web Page, Complete (*.htm;*.html)|*.htm;*.html|" "Text File (*.txt)|*.txt||"; CFileDialog cf(FALSE, "htm", fileName.get(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, lpszFilter, this); if(cf.DoModal() == IDOK) { CString strFullPath = cf.GetPathName(); // Will be like: c:\tmp\junk.htm char *pStrFullPath = strFullPath.GetBuffer(0); // Get char * for later use CString strDataPath; char *pStrDataPath = NULL; if(cf.m_ofn.nFilterIndex == 2) { // cf.m_ofn.nFilterIndex == 2 indicates // user want to save the complete document including // all frames, images, scripts, stylesheets etc. int idxPeriod = strFullPath.ReverseFind('.'); strDataPath = strFullPath.Mid(0, idxPeriod); strDataPath += "_files"; // At this stage strDataPath will be of the form // c:\tmp\junk_files - assuming we're saving to a file // named junk.htm // Any images etc in the doc will be saved to a dir // with the name c:\tmp\junk_files pStrDataPath = strDataPath.GetBuffer(0); //Get char * for later use } // Save the file nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser)); // if(persist) // persist->SaveDocument(nsnull, pStrFullPath, pStrDataPath); } }
void CBrowserView::OnSaveLinkAs() { if(! mCtxMenuLinkUrl.Length()) return; // Try to get the file name part from the URL // To do that we first construct an obj which supports // nsIRUI interface. Makes it easy to extract portions // of a URL like the filename, scheme etc. + We'll also // use it while saving this link to a file nsresult rv = NS_OK; nsCOMPtr<nsIURI> linkURI; rv = NS_NewURI(getter_AddRefs(linkURI), mCtxMenuLinkUrl); if (NS_FAILED(rv)) return; // Get the "path" portion (see nsIURI.h for more info // on various parts of a URI) nsCAutoString fileName; linkURI->GetPath(fileName); // The path may have the "/" char in it - strip those fileName.StripChars("\\/"); // Now, use this file name in a File Save As dlg... char *lpszFilter = "HTML Files (*.htm;*.html)|*.htm;*.html|" "Text Files (*.txt)|*.txt|" "All Files (*.*)|*.*||"; const char *pFileName = fileName.Length() ? fileName.get() : NULL; CFileDialog cf(FALSE, "htm", pFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, lpszFilter, this); if(cf.DoModal() == IDOK) { CString strFullPath = cf.GetPathName(); nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser)); // if(persist) // persist->SaveURI(linkURI, nsnull, strFullPath.GetBuffer(0)); } }
void pluto_persist(lua_State *L, lua_Chunkwriter writer, void *ud) { PersistInfo pi; pi.counter = 0; pi.L = L; pi.writer = writer; pi.ud = ud; #ifdef PLUTO_DEBUG pi.level = 0; #endif lua_checkstack(L, 4); /* perms? rootobj? ...? */ lua_assert(lua_gettop(L) == 2); /* perms rootobj */ lua_assert(!lua_isnil(L, 2)); /* perms rootobj */ lua_newtable(L); /* perms rootobj reftbl */ /* Now we're going to make the table weakly keyed. This prevents the * GC from visiting it and trying to mark things it doesn't want to * mark in tables, e.g. upvalues. All objects in the table are * a priori reachable, so it doesn't matter that we do this. */ lua_newtable(L); /* perms rootobj reftbl mt */ lua_pushstring(L, "__mode"); /* perms rootobj reftbl mt "__mode" */ lua_pushstring(L, "k"); /* perms rootobj reftbl mt "__mode" "k" */ lua_settable(L, 4); /* perms rootobj reftbl mt */ lua_setmetatable(L, 3); /* perms rootobj reftbl */ lua_insert(L, 2); /* perms reftbl rootobj */ persist(&pi); /* perms reftbl rootobj */ lua_remove(L, 2); /* perms rootobj */ }
static void persistuserdata(PersistInfo *pi) { /* perms reftbl ... udata */ if(persistspecialobject(pi, 0)) { /* perms reftbl ... udata */ return; } else { /* Use literal persistence */ int length = uvalue(getobject(pi->L, -2))->uv.len; pi->writer(pi->L, &length, sizeof(int), pi->ud); pi->writer(pi->L, lua_touserdata(pi->L, -1), length, pi->ud); if(!lua_getmetatable(pi->L, -1)) { /* perms reftbl ... udata */ lua_pushnil(pi->L); /* perms reftbl ... udata mt/nil */ } persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... udata */ } }
void HttpCredentialsGui::askFromUserAsync() { QString msg = tr("Please enter %1 password:<br>" "<br>" "User: %2<br>" "Account: %3<br>") .arg(Utility::escape(Theme::instance()->appNameGUI()), Utility::escape(_user), Utility::escape(_account->displayName())); QString reqTxt = requestAppPasswordText(_account); if (!reqTxt.isEmpty()) { msg += QLatin1String("<br>") + reqTxt + QLatin1String("<br>"); } if (!_fetchErrorString.isEmpty()) { msg += QLatin1String("<br>") + tr("Reading from keychain failed with error: '%1'").arg( Utility::escape(_fetchErrorString)) + QLatin1String("<br>"); } QInputDialog dialog; dialog.setWindowTitle(tr("Enter Password")); dialog.setLabelText(msg); dialog.setTextValue(_previousPassword); dialog.setTextEchoMode(QLineEdit::Password); if (QLabel *dialogLabel = dialog.findChild<QLabel *>()) { dialogLabel->setOpenExternalLinks(true); dialogLabel->setTextFormat(Qt::RichText); } bool ok = dialog.exec(); if (ok) { _password = dialog.textValue(); _ready = true; persist(); } emit asked(); }
static void execute() { while (1) { load_msgs(); if (msgs->size < 1) break; for (size_t i = 0; i < ROW_SIZE; ++i) { fdja_value *j = flu_list_shift(msgs); if (j == NULL) break; //fgaj_i(fdja_tod(j)); //fgaj_i(fdja_to_djan(j, 0)); //fdja_putdc(j); fdja_value *point = fdja_l(j, "point"); char p = point ? *fdja_srk(point) : 0; if (p == 'e') handle_execute(p, j); else if (p == 'r' || p == 'c') // receive or cancel handle_return(p, j); else if (p) handle_event(p, j); else reject_or_discard_msg(p, j); fdja_free(j); } } persist(); }
MqttReceiver::MqttReceiver(const MessagingSettings& settings) : channelCreatedSemaphore(new joynr::Semaphore(0)), isChannelCreated(false), channelIdForMqttTopic(), globalClusterControllerAddress(), receiverId(), settings(settings), mosquittoSubscriber(settings.getBrokerUrl(), globalClusterControllerAddress, channelCreatedSemaphore), mqttSettings() { MessagingPropertiesPersistence persist(settings.getMessagingPropertiesPersistenceFilename()); channelIdForMqttTopic = persist.getChannelId(); std::string brokerUri = "tcp://" + settings.getBrokerUrl().getBrokerChannelsBaseUrl().getHost() + ":" + std::to_string(settings.getBrokerUrl().getBrokerChannelsBaseUrl().getPort()); system::RoutingTypes::MqttAddress receiveMqttAddress(brokerUri, channelIdForMqttTopic); globalClusterControllerAddress = JsonSerializer::serialize(receiveMqttAddress); receiverId = persist.getReceiverId(); mosquittoSubscriber.registerChannelId(channelIdForMqttTopic); }
int EmbedWindow::SaveAs(char *fname, char *dirname) { nsresult rv; nsCOMPtr<nsIWebBrowserPersist> persist(do_GetInterface(mWebBrowser, &rv)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsILocalFile> file; NS_NewNativeLocalFile(nsDependentCString(fname), PR_TRUE, getter_AddRefs(file)); /* the nsIWebBrowserPersist wants a parent directory where to download images and other items related to the document */ /* we have to provide a directory, otherwise the current SaveDocument is marked as not finished and the next one is aborted */ nsCOMPtr<nsILocalFile> parentDirAsLocal; rv = NS_NewNativeLocalFile(nsDependentCString( dirname ), PR_TRUE, getter_AddRefs(parentDirAsLocal)); if (NS_FAILED(rv)) return rv; PRUint32 flags; persist->GetPersistFlags( &flags ); if( !(flags & nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES ) ) persist->SetPersistFlags( nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES ); persist->SaveDocument(nsnull, file, parentDirAsLocal, nsnull, 0, 0); return 0; }
void OctreePersistThread::aboutToFinish() { qDebug() << "Persist thread about to finish..."; persist(); qDebug() << "Persist thread done with about to finish..."; }
// // FUNCTION: SaveWebPage() // // PURPOSE: Saves the contents of the web page to a file // void SaveWebPage(nsIWebBrowser *aWebBrowser) { // Use the browser window title as the initial file name nsCOMPtr<nsIBaseWindow> webBrowserAsWin = do_QueryInterface(aWebBrowser); nsXPIDLString windowTitle; webBrowserAsWin->GetTitle(getter_Copies(windowTitle)); nsCString fileName; fileName.AssignWithConversion(windowTitle); // Sanitize the title of all illegal characters fileName.CompressWhitespace(); // Remove whitespace from the ends fileName.StripChars("\\*|:\"><?"); // Strip illegal characters fileName.ReplaceChar('.', L'_'); // Dots become underscores fileName.ReplaceChar('/', L'-'); // Forward slashes become hyphens // Copy filename to a character buffer char szFile[_MAX_PATH]; memset(szFile, 0, sizeof(szFile)); PL_strncpyz(szFile, fileName.get(), sizeof(szFile) - 1); // XXXldb probably should be just sizeof(szfile) // Initialize the file save as information structure OPENFILENAME saveFileNameInfo; memset(&saveFileNameInfo, 0, sizeof(saveFileNameInfo)); saveFileNameInfo.lStructSize = sizeof(saveFileNameInfo); saveFileNameInfo.hwndOwner = NULL; saveFileNameInfo.hInstance = NULL; saveFileNameInfo.lpstrFilter = "Web Page, HTML Only (*.htm;*.html)\0*.htm;*.html\0" "Web Page, Complete (*.htm;*.html)\0*.htm;*.html\0" "Text File (*.txt)\0*.txt\0"; saveFileNameInfo.lpstrCustomFilter = NULL; saveFileNameInfo.nMaxCustFilter = NULL; saveFileNameInfo.nFilterIndex = 1; saveFileNameInfo.lpstrFile = szFile; saveFileNameInfo.nMaxFile = sizeof(szFile); saveFileNameInfo.lpstrFileTitle = NULL; saveFileNameInfo.nMaxFileTitle = 0; saveFileNameInfo.lpstrInitialDir = NULL; saveFileNameInfo.lpstrTitle = NULL; saveFileNameInfo.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; saveFileNameInfo.nFileOffset = NULL; saveFileNameInfo.nFileExtension = NULL; saveFileNameInfo.lpstrDefExt = "htm"; saveFileNameInfo.lCustData = NULL; saveFileNameInfo.lpfnHook = NULL; saveFileNameInfo.lpTemplateName = NULL; if (GetSaveFileName(&saveFileNameInfo)) { // Does the user want to save the complete document including // all frames, images, scripts, stylesheets etc. ? char *pszDataPath = NULL; if (saveFileNameInfo.nFilterIndex == 2) // 2nd choice means save everything { static char szDataFile[_MAX_PATH]; char szDataPath[_MAX_PATH]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath(szFile, drive, dir, fname, ext); sprintf(szDataFile, "%s_files", fname); _makepath(szDataPath, drive, dir, szDataFile, ""); pszDataPath = szDataPath; } // Save away nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aWebBrowser)); nsCOMPtr<nsILocalFile> file; NS_NewNativeLocalFile(nsDependentCString(szFile), TRUE, getter_AddRefs(file)); nsCOMPtr<nsILocalFile> dataPath; if (pszDataPath) { NS_NewNativeLocalFile(nsDependentCString(pszDataPath), TRUE, getter_AddRefs(dataPath)); } persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0); } }
bool OctreePersistThread::process() { if (!_initialLoadComplete) { quint64 loadStarted = usecTimestampNow(); qDebug() << "loading Octrees from file: " << _filename << "..."; bool persistantFileRead; _tree->lockForWrite(); { PerformanceWarning warn(true, "Loading Octree File", true); persistantFileRead = _tree->readFromSVOFile(_filename.toLocal8Bit().constData()); _tree->pruneTree(); } _tree->unlock(); quint64 loadDone = usecTimestampNow(); _loadTimeUSecs = loadDone - loadStarted; _tree->clearDirtyBit(); // the tree is clean since we just loaded it qDebug("DONE loading Octrees from file... fileRead=%s", debug::valueOf(persistantFileRead)); unsigned long nodeCount = OctreeElement::getNodeCount(); unsigned long internalNodeCount = OctreeElement::getInternalNodeCount(); unsigned long leafNodeCount = OctreeElement::getLeafNodeCount(); qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves", nodeCount, internalNodeCount, leafNodeCount); bool wantDebug = false; if (wantDebug) { double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls(); qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls() << " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet; double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls(); qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls() << " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perSet=" << usecPerSet; } _initialLoadComplete = true; _lastBackup = _lastCheck = usecTimestampNow(); // we just loaded, no need to save again time(&_lastPersistTime); emit loadCompleted(); } if (isStillRunning()) { quint64 MSECS_TO_USECS = 1000; quint64 USECS_TO_SLEEP = 10 * MSECS_TO_USECS; // every 10ms usleep(USECS_TO_SLEEP); // do our updates then check to save... _tree->update(); quint64 now = usecTimestampNow(); quint64 sinceLastSave = now - _lastCheck; quint64 intervalToCheck = _persistInterval * MSECS_TO_USECS; if (sinceLastSave > intervalToCheck) { _lastCheck = now; persist(); } } // if we were asked to debugTimestampNow do that now... if (_debugTimestampNow) { quint64 now = usecTimestampNow(); quint64 sinceLastDebug = now - _lastTimeDebug; quint64 DEBUG_TIMESTAMP_INTERVAL = 600000000; // every 10 minutes if (sinceLastDebug > DEBUG_TIMESTAMP_INTERVAL) { _lastTimeDebug = usecTimestampNow(true); // ask for debug output } } return isStillRunning(); // keep running till they terminate us }
/* Choose whether to do a regular or special persistence based on an object's * metatable. "default" is whether the object, if it doesn't have a __persist * entry, is literally persistable or not. * Pushes the unpersist closure and returns true if special persistence is * used. */ static int persistspecialobject(PersistInfo *pi, int defaction) { /* perms reftbl ... obj */ lua_checkstack(pi->L, 4); /* Check whether we should persist literally, or via the __persist * metafunction */ if(!lua_getmetatable(pi->L, -1)) { if(defaction) { { int zero = 0; pi->writer(pi->L, &zero, sizeof(int), pi->ud); } return 0; } else { lua_pushstring(pi->L, "Type not literally persistable by default"); lua_error(pi->L); } } /* perms reftbl sptbl ... obj mt */ lua_pushstring(pi->L, "__persist"); /* perms reftbl sptbl ... obj mt "__persist" */ lua_rawget(pi->L, -2); /* perms reftbl sptbl ... obj mt __persist? */ if(lua_isnil(pi->L, -1)) { /* perms reftbl sptbl ... obj mt nil */ lua_pop(pi->L, 2); /* perms reftbl sptbl ... obj */ if(defaction) { { int zero = 0; pi->writer(pi->L, &zero, sizeof(int), pi->ud); } return 0; } else { lua_pushstring(pi->L, "Type not literally persistable by default"); lua_error(pi->L); return 0; /* not reached */ } } else if(lua_isboolean(pi->L, -1)) { /* perms reftbl sptbl ... obj mt bool */ if(lua_toboolean(pi->L, -1)) { /* perms reftbl sptbl ... obj mt true */ lua_pop(pi->L, 2); /* perms reftbl sptbl ... obj */ { int zero = 0; pi->writer(pi->L, &zero, sizeof(int), pi->ud); } return 0; } else { lua_pushstring(pi->L, "Metatable forbade persistence"); lua_error(pi->L); return 0; /* not reached */ } } else if(!lua_isfunction(pi->L, -1)) { lua_pushstring(pi->L, "__persist not nil, boolean, or function"); lua_error(pi->L); } /* perms reftbl ... obj mt __persist */ lua_pushvalue(pi->L, -3); /* perms reftbl ... obj mt __persist obj */ #ifdef PLUTO_PASS_USERDATA_TO_PERSIST lua_pushlightuserdata(pi->L, (void*)pi->writer); lua_pushlightuserdata(pi->L, pi->ud); /* perms reftbl ... obj mt __persist obj ud */ lua_call(pi->L, 3, 1); /* perms reftbl ... obj mt func? */ #else lua_call(pi->L, 1, 1); /* perms reftbl ... obj mt func? */ #endif /* perms reftbl ... obj mt func? */ if(!lua_isfunction(pi->L, -1)) { lua_pushstring(pi->L, "__persist function did not return a function"); lua_error(pi->L); } /* perms reftbl ... obj mt func */ { int one = 1; pi->writer(pi->L, &one, sizeof(int), pi->ud); } persist(pi); /* perms reftbl ... obj mt func */ lua_pop(pi->L, 2); /* perms reftbl ... obj */ return 1; }
/* Persist all stack members */ static void persistthread(PersistInfo *pi) { size_t posremaining; lua_State *L2; /* perms reftbl ... thr */ L2 = lua_tothread(pi->L, -1); lua_checkstack(pi->L, L2->top - L2->stack + 1); if(pi->L == L2) { lua_pushstring(pi->L, "Can't persist currently running thread"); lua_error(pi->L); return; /* not reached */ } /* Persist the stack */ posremaining = revappendstack(L2, pi->L); /* perms reftbl ... thr (rev'ed contents of L2) */ pi->writer(pi->L, &posremaining, sizeof(size_t), pi->ud); for(; posremaining > 0; posremaining--) { persist(pi); lua_pop(pi->L, 1); } /* perms reftbl ... thr */ /* Now, persist the CallInfo stack. */ { size_t i, numframes = (L2->ci - L2->base_ci) + 1; pi->writer(pi->L, &numframes, sizeof(size_t), pi->ud); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; size_t stackbase = ci->base - L2->stack; size_t stackfunc = ci->func - L2->stack; size_t stacktop = ci->top - L2->stack; size_t savedpc = (ci != L2->base_ci) ? ci->savedpc - ci_func(ci)->l.p->code : 0; pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); pi->writer(pi->L, &stackfunc, sizeof(size_t), pi->ud); pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); pi->writer(pi->L, &ci->nresults, sizeof(int), pi->ud); pi->writer(pi->L, &savedpc, sizeof(size_t), pi->ud); } } /* Serialize the state's other parameters, with the exception of upval stuff */ { size_t stackbase = L2->base - L2->stack; size_t stacktop = L2->top - L2->stack; lua_assert(L2->nCcalls <= 1); pi->writer(pi->L, &L2->status, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); pi->writer(pi->L, &L2->errfunc, sizeof(ptrdiff_t), pi->ud); } /* Finally, record upvalues which need to be reopened */ /* See the comment above persistupval() for why we do this */ { GCObject *gco; UpVal *uv; /* perms reftbl ... thr */ for(gco = L2->openupval; gco != NULL; gco = uv->next) { size_t stackpos; uv = gco2uv(gco); /* Make sure upvalue is really open */ lua_assert(uv->v != &uv->u.value); pushupval(pi->L, uv); /* perms reftbl ... thr uv */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ stackpos = uv->v - L2->stack; pi->writer(pi->L, &stackpos, sizeof(size_t), pi->ud); } /* perms reftbl ... thr */ lua_pushnil(pi->L); /* perms reftbl ... thr nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ } /* perms reftbl ... thr */ }
/* Top-level delegating persist function */ static void persist(PersistInfo *pi) { /* perms reftbl ... obj */ lua_checkstack(pi->L, 2); /* If the object has already been written, write a reference to it */ lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_rawget(pi->L, 2); /* perms reftbl ... obj ref? */ if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj ref */ int zero = 0; int ref = (int)lua_touserdata(pi->L, -1); pi->writer(pi->L, &zero, sizeof(int), pi->ud); pi->writer(pi->L, &ref, sizeof(int), pi->ud); lua_pop(pi->L, 1); /* perms reftbl ... obj ref */ #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 %d\n", ref); #endif return; } /* perms reftbl ... obj nil */ lua_pop(pi->L, 1); /* perms reftbl ... obj */ /* If the object is nil, write the pseudoreference 0 */ if(lua_isnil(pi->L, -1)) { int zero = 0; /* firsttime */ pi->writer(pi->L, &zero, sizeof(int), pi->ud); /* ref */ pi->writer(pi->L, &zero, sizeof(int), pi->ud); #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 0\n"); #endif return; } { /* indicate that it's the first time */ int one = 1; pi->writer(pi->L, &one, sizeof(int), pi->ud); } lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_pushlightuserdata(pi->L, (void*)(++(pi->counter))); /* perms reftbl ... obj obj ref */ lua_rawset(pi->L, 2); /* perms reftbl ... obj */ pi->writer(pi->L, &pi->counter, sizeof(int), pi->ud); /* At this point, we'll give the permanents table a chance to play. */ { lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_gettable(pi->L, 1); /* perms reftbl ... obj permkey? */ if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj permkey */ int type = PLUTO_TPERMANENT; #ifdef PLUTO_DEBUG printindent(pi->level); printf("1 %d PERM\n", pi->counter); pi->level++; #endif pi->writer(pi->L, &type, sizeof(int), pi->ud); persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... obj */ #ifdef PLUTO_DEBUG pi->level--; #endif return; } else { /* perms reftbl ... obj nil */ lua_pop(pi->L, 1); /* perms reftbl ... obj */ } /* perms reftbl ... obj */ } { int type = lua_type(pi->L, -1); pi->writer(pi->L, &type, sizeof(int), pi->ud); #ifdef PLUTO_DEBUG printindent(pi->level); printf("1 %d %d\n", pi->counter, type); pi->level++; #endif } switch(lua_type(pi->L, -1)) { case LUA_TBOOLEAN: persistboolean(pi); break; case LUA_TLIGHTUSERDATA: persistlightuserdata(pi); break; case LUA_TNUMBER: persistnumber(pi); break; case LUA_TSTRING: persiststring(pi); break; case LUA_TTABLE: persisttable(pi); break; case LUA_TFUNCTION: persistfunction(pi); break; case LUA_TTHREAD: persistthread(pi); break; case LUA_TPROTO: persistproto(pi); break; case LUA_TUPVAL: persistupval(pi); break; case LUA_TUSERDATA: persistuserdata(pi); break; default: lua_assert(0); } #ifdef PLUTO_DEBUG pi->level--; #endif }
int main(int argc, char *argv[]) { size_t path_len, total_files; off_t bytes_wasted, total_wasted; char path_buffer[PATH_MAX_LEN], *hash_value; struct file_entry_t *file_entry, *trie_entry; SListIterator slist_iterator; SetIterator set_iterator; /* Step 0: Session data */ struct file_info_t file_info; clear_info(&file_info); /* Step 1: Parse arguments */ while (--argc) { /* Being unable to record implies insufficient resources */ if (!record(argv[argc], &file_info)){ fprintf(stderr, "[FATAL] out of memory\n"); destroy_info(&file_info); return (EXIT_FAILURE); } } /* Step 2: Fully explore any directories specified */ #ifndef NDEBUG printf("[DEBUG] Creating file list...\n"); #endif while (slist_length(file_info.file_stack) > 0) { /* Pick off the top of the file stack */ file_entry = (struct file_entry_t *)(slist_data(file_info.file_stack)); slist_remove_entry(&file_info.file_stack, file_info.file_stack); assert(file_entry->type == DIRECTORY); /* Copy the basename to a buffer */ memset(path_buffer, '\0', PATH_MAX_LEN); path_len = strnlen(file_entry->path, PATH_MAX_LEN); memcpy(path_buffer, file_entry->path, path_len); /* Ignore cases that would cause overflow */ if (path_len < PATH_MAX_LEN) { /* Append a trailing slash */ path_buffer[path_len] = '/'; /* Record all contents (may push onto file stack or one of the lists) */ DIR *directory = opendir(file_entry->path); if (traverse(&file_info, directory, path_buffer, ++path_len)) { fprintf(stderr, "[FATAL] out of memory\n"); destroy_info(&file_info); return (EXIT_FAILURE); } else if (closedir(directory)) { fprintf(stderr, "[WARNING] '%s' (close failed)\n", file_entry->path); } } /* Discard this entry */ destroy_entry(file_entry); } /* Step 3: Warn about any ignored files */ if (slist_length(file_info.bad_files) > 0) { slist_iterate(&file_info.bad_files, &slist_iterator); while (slist_iter_has_more(&slist_iterator)) { file_entry = slist_iter_next(&slist_iterator); fprintf(stderr, "[WARNING] '%s' ", file_entry->path); switch (file_entry->type) { case INVALID: ++file_info.invalid_files; fprintf(stderr, "(invalid file)\n"); break; case INACCESSIBLE: ++file_info.protected_files; fprintf(stderr, "(protected file)\n"); break; default: ++file_info.irregular_files; fprintf(stderr, "(irregular file)\n"); break; } } fprintf(stderr, "[WARNING] %lu file(s) ignored\n", (long unsigned)(num_errors(&file_info))); } #ifndef NDEBUG if (num_errors(&file_info) > 0) { fprintf(stderr, "[FATAL] cannot parse entire file tree\n"); destroy_info(&file_info); return (EXIT_FAILURE); } printf("[DEBUG] Found %lu / %lu valid files\n", (unsigned long)(num_files(&file_info)), (unsigned long)(file_info.total_files)); #endif /* Step 4: Begin the filtering process */ #ifndef NDEBUG printf("[DEBUG] Creating file table...\n"); #endif if (slist_length(file_info.good_files) > 0) { file_info.hash_trie = trie_new(); file_info.shash_trie = trie_new(); optimize_filter(&file_info); /* Extract each file from the list (they should all be regular) */ slist_iterate(&file_info.good_files, &slist_iterator); while (slist_iter_has_more(&slist_iterator)) { file_entry = slist_iter_next(&slist_iterator); assert(file_entry->type == REGULAR); /* Perform a "shallow" hash of the file */ hash_value = hash_entry(file_entry, SHALLOW); #ifndef NDEBUG printf("[SHASH] %s\t*%s\n", file_entry->path, hash_value); #endif /* Check to see if we might have seen this file before */ if (bloom_filter_query(file_info.shash_filter, hash_value)) { /* Get the full hash of the new file */ hash_value = hash_entry(file_entry, FULL); #ifndef NDEBUG printf("[+HASH] %s\t*%s\n", file_entry->path, hash_value); #endif archive(&file_info, file_entry); /* Check to see if bloom failed us */ trie_entry = trie_lookup(file_info.shash_trie, file_entry->shash); if (trie_entry == TRIE_NULL) { #ifndef NDEBUG printf("[DEBUG] '%s' (false positive)\n", file_entry->path); #endif trie_insert(file_info.shash_trie, file_entry->shash, file_entry); } else { /* Get the full hash of the old file */ hash_value = hash_entry(trie_entry, FULL); #ifndef NDEBUG if (hash_value) { printf("[-HASH] %s\t*%s\n", trie_entry->path, hash_value); } #endif archive(&file_info, trie_entry); } } else { /* Add a record of this shash to the filter */ bloom_filter_insert(file_info.shash_filter, hash_value); trie_insert(file_info.shash_trie, hash_value, file_entry); } } persist("bloom_store", &file_info); } /* Step 5: Output results and cleanup before exit */ printf("[EXTRA] Found %lu sets of duplicates...\n", (unsigned long)(slist_length(file_info.duplicates))); slist_iterate(&file_info.duplicates, &slist_iterator); for (total_files = total_wasted = bytes_wasted = 0; slist_iter_has_more(&slist_iterator); total_wasted += bytes_wasted) { Set *set = slist_iter_next(&slist_iterator); int size = set_num_entries(set); if (size < 2) { continue; } printf("[EXTRA] %lu files (w/ same hash):\n", (unsigned long)(size)); set_iterate(set, &set_iterator); for (bytes_wasted = 0; set_iter_has_more(&set_iterator); bytes_wasted += file_entry->size, ++total_files) { file_entry = set_iter_next(&set_iterator); printf("\t%s (%lu bytes)\n", file_entry->path, (unsigned long)(file_entry->size)); } } printf("[EXTRA] %lu bytes in %lu files (wasted)\n", (unsigned long)(total_wasted), (unsigned long)(total_files)); destroy_info(&file_info); return (EXIT_SUCCESS); }
STDMETHODIMP C_Items::Store(I_Archive * arc) { if (!arc) return E_POINTER; //TODO - templatize this function and stick it in a base class. try { long len; get_Count(&len); BOOL bIsFinal; arc->get_IsFinal(&bIsFinal); Sort(); for (unsigned int n = 0; n < len; n++) { C_ItemPtr item = GetItem(n); if (item) { BOOL bStore = TRUE; if (bIsFinal) { BOOL bDeleted = FALSE; item->get_Deleted(&bDeleted); bStore = !bDeleted; } C_PersistentPtr persist(item); if (persist && bStore) { BOOL bIsEmpty = FALSE; persist->get_IsEmpty(&bIsEmpty); if (bIsEmpty) { len--; } } } n++; } if (len > 0) { for (unsigned int n = 0; n < len; n++) { C_ItemPtr item = GetItem(n); if (item) { BOOL bStore = TRUE; if (bIsFinal) { BOOL bDeleted = FALSE; item->get_Deleted(&bDeleted); bStore = !bDeleted; } C_PersistentPtr persist(item); if (persist && bStore) { BOOL bIsEmpty = FALSE; persist->get_IsEmpty(&bIsEmpty); if (!bIsEmpty) { // TODO: Associative array behaviour persist->Serialise(arc); } } } } } } catch (C_STLNonStackException const &exception) { exception.Log(_T("Exception in C_Items::Store")); } return S_OK; }
STDMETHODIMP C_Items::Retrieve(I_Archive * arc) { if (!arc) return E_POINTER; C_STLException::install(); //TODO - templatize this function and stick it in a base class. try { BSTR bs = NULL; unsigned int len = 0; if (S_OK != arc->RetrieveString(&bs)) { return E_FAIL; } String s(bs); s.toLower(); String::FreeBSTR(&bs); static String tags[5] = { _T("mmp:item"), _T("mmp:text"), _T("mmp:node"), _T("mmp:picture"), _T("mmp:branch") }; typedef enum ematches { plainitem, text, node, picture, branch }; static String types[4] = { _T("node"), _T("text-block"), _T("picture"), _T("branch") }; ematches match = plainitem; CLSID clsid; IID iid; StringPtr ptr(s.Find(tags[plainitem])); StringPtr ptrKill(s.Find(tags[plainitem])); for (unsigned int test = plainitem; test <= branch; test++) { ptr = s.Find(tags[test]); if (ptr.isValid()) { ptrKill = s.Find(String(_T("/")) + tags[test]); match = static_cast<ematches>(test); break; } } switch (match) { case node: clsid = CLSID_Node; iid = IID_I_Node; break; case text: clsid = CLSID_TextBlock; iid = IID_I_TextBlock; break; case picture: clsid = CLSID_Picture; iid = IID_I_Picture; break; case branch: clsid = CLSID_Branch; iid = IID_I_Branch; break; } while (ptr.isValid() && !ptrKill.isValid()) {//Check this is the start of an item... C_ItemPtr item; ///////////////////////////////////////////////////// // In a paste operation, the object's GUID must be ignored // - a new object is being created with its own identity. BOOL b = FALSE; BOOL bPreserveID = TRUE; BSTR bs = NULL; arc->get_PreserveIdentities(&bPreserveID); if (bPreserveID) { ///////////////////////////////////////////////////// // Get the GUID to identify the object. Check if it // exists already - if so, divert the serialisation data // to the existing object and add a reference to the // Children collection. String sUUID; StringPtr ptrUUID = s.Find(_T("uuid")); if (ptrUUID.isValid()) { StringPtr ptrLeft = s.Find(_T("\""), ptrUUID); ptrLeft++; if (ptrLeft.isValid()) { StringPtr ptrRight = s.Find(_T("\""), ptrLeft); if (ptrRight.isValid()) { sUUID = s.Mid(ptrLeft.Index(), ptrRight.Index() - ptrLeft.Index()); } else { sUUID = s.Right(s.GetLength() - ptrLeft.Index()); } T_SafeArray<char> buffer(sUUID.GetLength() + 1); ::_stprintf(buffer[0], _T("%s\0"), sUUID.toLPCTSTR()); GUID guid = String(buffer[0]).toGUID(); map<GUID, I_MapItem*>::iterator it = m_S_Items.find(guid); if (it != m_S_Items.end()) { //The object with this GUID already exists in the item map item = (*it).second; _ASSERTE(item); if (item) { VARIANT v; C_UniquePtr unique(item); if (unique) { unique->get_UID(&bs); } VariantInit(&v); v.vt = VT_BSTR; v.bstrVal = bs; get_Exists(v, &b); if (!b) { // Add the item to the collection Add(bs, item); b = TRUE; } } } } } } if (b) { if (bs) { String::FreeBSTR(&bs); } } else { if (match == plainitem) { int type = -1; StringPtr ptrType = s.Find(_T("type")); String sType; if (ptrType.isValid()) { StringPtr ptrLeft = s.Find(_T("\""), ptrType); if (ptrLeft.isValid()) { ptrLeft++; StringPtr ptrRight = s.Find(_T("\""), ptrLeft); if (ptrRight.isValid()) { sType = s.Mid(ptrLeft.Index(), ptrRight.Index() - ptrLeft.Index()); } else { sType = s.Right(s.GetLength() - ptrLeft.Index()); } for (int n = 0; n < 4; n++) { if (sType == types[n]) { type = n; switch (type) { case 0: clsid = CLSID_Node; iid = IID_I_Node; break; case 1: clsid = CLSID_TextBlock; iid = IID_I_TextBlock; break; case 2: clsid = CLSID_Picture; iid = IID_I_Picture; break; case 3: clsid = CLSID_Branch; iid = IID_I_Branch; break; } break; } } } } if (type < 0) { ///////////////////////////////////////////////////// // Get the CLSID and IID to identify the object's type String sCLSID; StringPtr ptrCLSID = s.Find(_T("clsid")); StringPtr ptrLeft = s.Find(_T("\""), ptrCLSID); ptrLeft++; StringPtr ptrRight = s.Find(_T("\""), ptrLeft); if (ptrRight.isValid()) { sCLSID = s.Mid(ptrLeft.Index(), ptrRight.Index() - ptrLeft.Index()); } else { sCLSID = s.Right(s.GetLength() - ptrLeft.Index()); } bs = sCLSID.toBSTR(); CLSIDFromString(bs, &clsid); String::FreeBSTR(&bs); String sIID; StringPtr ptrIID = s.Find(_T("iid")); ptrLeft = s.Find(_T("\""), ptrIID); ptrLeft++; ptrRight = s.Find(_T("\""), ptrLeft); if (ptrRight.isValid()) { sIID = s.Mid(ptrLeft.Index(), ptrRight.Index() - ptrLeft.Index()); } else { sIID = s.Right(s.GetLength() - ptrLeft.Index()); } bs = sIID.toBSTR(); IIDFromString(bs, &iid); String::FreeBSTR(&bs); } } // TODO: Drop the string parameter item = NewItem(clsid, iid, String(_T(""))); } if (item) { arc->Rollback(); C_PersistentPtr persist(item); if (persist) { persist->Serialise(arc); C_DrawingStrategyPtr strategy(item); if (strategy) { strategy->putref_Parent(m_pParent); } BOOL bHasFocus = FALSE; item->get_HasFocus(&bHasFocus); if (bHasFocus) { I_ECBDiagram *map = NULL; if (m_pParent) { m_pParent->get_Map(&map); } if (map) { map->putref_CurrentSelection(item); map->Release(); } } } } if (match == plainitem) { // Discard closing tag if (S_OK != arc->RetrieveString(&bs)) { return E_FAIL; } s = bs; String::FreeBSTR(&bs); s = s.toLower(); ptr = s.Find(tags[match]); ptrKill = s.Find(String(_T("/")) + tags[match]); } else { break; } } if (match == plainitem && !ptrKill.isValid()) { //...if it isn't, it doesn't belong here! arc->Rollback(); } // Sort the items as soon as they're retrieved Sort(); } catch (C_STLNonStackException const &exception) { exception.Log(_T("Exception in C_Items::Retrieve")); } return S_OK; }
void DatabaseSession::persist_redirected(URL const& old_url, ToBeCrawled const& cron, AnalyseResults const& analyse) { ///TODO modifier tout ce qui est en rapport avec old_url persist(cron, analyse); }
/* Persist all stack members */ static void persistthread(PersistInfo *pi) { int posremaining; lua_State *L2; /* perms reftbl ... thr */ L2 = lua_tothread(pi->L, -1); if(pi->L == L2) { lua_pushstring(pi->L, "Can't persist currently running thread"); lua_error(pi->L); return; /* not reached */ } posremaining = revappendstack(L2, pi->L); /* perms reftbl ... thr (rev'ed contents of L2) */ pi->writer(pi->L, &posremaining, sizeof(int), pi->ud); for(; posremaining > 0; posremaining--) { persist(pi); lua_pop(pi->L, 1); } /* perms reftbl ... thr */ /* Now, persist the CallInfo stack. */ { int i, numframes = (L2->ci - L2->base_ci) + 1; pi->writer(pi->L, &numframes, sizeof(int), pi->ud); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; int stackbase = ci->base - L2->stack; int stacktop = ci->top - L2->stack; int pc = (ci != L2->base_ci) ? ci->u.l.savedpc - ci_func(ci)->l.p->code : 0; pi->writer(pi->L, &stackbase, sizeof(int), pi->ud); pi->writer(pi->L, &stacktop, sizeof(int), pi->ud); pi->writer(pi->L, &pc, sizeof(int), pi->ud); pi->writer(pi->L, &(ci->state), sizeof(int), pi->ud); } } /* Serialize the state's top and base */ { int stackbase = L2->base - L2->stack; int stacktop = L2->top - L2->stack; pi->writer(pi->L, &stackbase, sizeof(int), pi->ud); pi->writer(pi->L, &stacktop, sizeof(int), pi->ud); } /* Finally, record upvalues which need to be reopened */ /* See the comment above persistupval() for why we do this */ { UpVal *uv; /* perms reftbl ... thr */ for(uv = gcotouv(L2->openupval); uv != NULL; uv = gcotouv(uv->next)) { int stackpos; /* Make sure upvalue is really open */ lua_assert(uv->v != &uv->value); pushupval(pi->L, uv); /* perms reftbl ... thr uv */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ stackpos = uv->v - L2->stack; pi->writer(pi->L, &stackpos, sizeof(int), pi->ud); } /* perms reftbl ... thr */ lua_pushnil(pi->L); /* perms reftbl ... thr nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ } /* perms reftbl ... thr */ }