RT_forget_package

This commit is contained in:
David Rose 2010-03-02 01:39:34 +00:00
parent b4927284b5
commit 6a2cb24ecf
8 changed files with 115 additions and 7 deletions

View File

@ -410,6 +410,9 @@ class AppRunner(DirectObject):
self.notify.info("Deleting host %s: %s" % (host.hostUrl, host.hostDir))
shutil.rmtree(host.hostDir.toOsSpecific(), True)
self.sendRequest('forget_package', host.hostUrl, '', '')
def freshenFile(self, host, fileSpec, localPathname):
""" Ensures that the localPathname is the most current version
of the file defined by fileSpec, as offered by host. If not,

View File

@ -485,6 +485,9 @@ class HostInfo:
self.notify.info("Deleting package %s: %s" % (package.packageName, package.getPackageDir()))
shutil.rmtree(package.getPackageDir().toOsSpecific(), True)
if self.appRunner:
self.appRunner.sendRequest('forget_package', self.hostUrl, package.packageName, package.packageVersion or '')
def __determineHostDir(self, hostDirBasename, hostUrl):
""" Hashes the host URL into a (mostly) unique directory
string, which will be the root of the host's install tree.

View File

@ -405,6 +405,7 @@ get_package_desc_file(FileSpec &desc_file, // out
void P3DHost::
forget_package(P3DPackage *package, const string &alt_host) {
string key = package->get_package_name() + "_" + package->get_package_version();
nout << "Forgetting package " << key << "\n";
PackageMap &package_map = _packages[alt_host];

View File

@ -743,6 +743,28 @@ get_request() {
(*func)(data);
}
break;
case P3D_RT_forget_package:
{
// We're being asked to forget a particular package.
const char *host_url = request->_request._forget_package._host_url;
const char *package_name = request->_request._forget_package._package_name;
const char *package_version = request->_request._forget_package._package_version;
if (package_version == NULL) {
package_version = "";
}
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
P3DHost *host = inst_mgr->get_host(host_url);
if (package_name != NULL) {
P3DPackage *package = host->get_package(package_name, package_version);
host->forget_package(package);
} else {
// If a NULL package name is given, forget the whole host.
inst_mgr->forget_host(host);
}
}
break;
}
}
@ -869,18 +891,38 @@ finish_request(P3D_request *request, bool handled) {
break;
case P3D_RT_get_url:
free((char *)request->_request._get_url._url);
request->_request._get_url._url = NULL;
if (request->_request._get_url._url != NULL) {
free((char *)request->_request._get_url._url);
request->_request._get_url._url = NULL;
}
break;
case P3D_RT_notify:
free((char *)request->_request._notify._message);
request->_request._notify._message = NULL;
if (request->_request._notify._message != NULL) {
free((char *)request->_request._notify._message);
request->_request._notify._message = NULL;
}
break;
case P3D_RT_forget_package:
if (request->_request._forget_package._host_url != NULL) {
free((char *)request->_request._forget_package._host_url);
request->_request._forget_package._host_url = NULL;
}
if (request->_request._forget_package._package_name != NULL) {
free((char *)request->_request._forget_package._package_name);
request->_request._forget_package._package_name = NULL;
}
if (request->_request._forget_package._package_version != NULL) {
free((char *)request->_request._forget_package._package_version);
request->_request._forget_package._package_version = NULL;
}
break;
}
p3d_unref_delete(((P3DInstance *)request->_instance));
request->_instance = NULL;
delete request;
}
@ -2245,6 +2287,27 @@ make_p3d_request(TiXmlElement *xrequest) {
request->_instance = NULL;
request->_request_type = P3D_RT_stop;
} else if (strcmp(rtype, "forget_package") == 0) {
const char *host_url = xrequest->Attribute("host_url");
if (host_url != NULL) {
// A Python-level request to remove a package from the cache.
request = new P3D_request;
request->_instance = NULL;
request->_request_type = P3D_RT_forget_package;
request->_request._forget_package._host_url = strdup(host_url);
request->_request._forget_package._package_name = NULL;
request->_request._forget_package._package_version = NULL;
const char *package_name = xrequest->Attribute("package_name");
const char *package_version = xrequest->Attribute("package_version");
if (package_name != NULL) {
request->_request._forget_package._package_name = strdup(package_name);
if (package_version != NULL) {
request->_request._forget_package._package_version = strdup(package_version);
}
}
}
} else {
nout << "Ignoring request of type " << rtype << "\n";
}

View File

@ -622,6 +622,8 @@ get_host(const string &host_url) {
void P3DInstanceManager::
forget_host(P3DHost *host) {
const string &host_url = host->get_host_url();
nout << "Forgetting host " << host_url << "\n";
// Hmm, this is a memory leak. But we allow it to remain, since
// it's an unusual circumstance (uninstalling), and it's safer to

View File

@ -1080,6 +1080,25 @@ py_request_func(PyObject *args) {
xrequest->SetAttribute("object_id", object_id);
write_xml(_pipe_write, &doc, nout);
} else if (strcmp(request_type, "forget_package") == 0) {
// A request to the instance to drop a particular package (or
// host) from the cache.
const char *host_url;
const char *package_name;
const char *package_version;
if (!PyArg_ParseTuple(extra_args, "sss", &host_url, &package_name, &package_version)) {
return NULL;
}
xrequest->SetAttribute("host_url", host_url);
if (*package_name) {
xrequest->SetAttribute("package_name", package_name);
if (*package_version) {
xrequest->SetAttribute("package_version", package_version);
}
}
write_xml(_pipe_write, &doc, nout);
} else {
string message = string("Unsupported request type: ") + string(request_type);
PyErr_SetString(PyExc_ValueError, message.c_str());

View File

@ -1290,7 +1290,8 @@ rt_thread_run() {
// Function: P3DSession::rt_handle_request
// Access: Private
// Description: Processes a single request or notification received
// from an instance.
// from an instance. This method runs in the read
// thread.
////////////////////////////////////////////////////////////////////
void P3DSession::
rt_handle_request(TiXmlDocument *doc) {

View File

@ -767,6 +767,7 @@ typedef enum {
P3D_RT_notify,
P3D_RT_refresh,
P3D_RT_callback,
P3D_RT_forget_package
} P3D_request_type;
/* Structures corresponding to the request types in the above enum. */
@ -792,8 +793,9 @@ typedef struct {
} P3D_request_get_url;
/* A general notification. This is just a message of some event
having occurred within the Panda3D instance. It may be safely
ignored.
having occurred within the Panda3D instance. The core API will
automatically trigger a JavaScript callback based on this event.
It may be safely ignored by the application.
*/
typedef struct {
const char *_message;
@ -818,6 +820,19 @@ typedef struct {
void *_data;
} P3D_request_callback;
/* A forget-package request. This is called when a Python application
wishes to uninstall a specific package (for instance, to clean up
disk space). It is assumed that the application will be
responsible for deleting the actual files of the package; this is
just an instruction to the core API to remove the indicated package
from the in-memory cache. This is handled internally, and
shouldn't be interpreted by the caller. */
typedef struct {
const char *_host_url;
const char *_package_name;
const char *_package_version;
} P3D_request_forget_package;
/* This is the overall structure that represents a single request. It
is returned by P3D_instance_get_request(). */
typedef struct {
@ -829,6 +844,7 @@ typedef struct {
P3D_request_notify _notify;
P3D_request_refresh _refresh;
P3D_request_callback _callback;
P3D_request_forget_package _forget_package;
} _request;
} P3D_request;