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)) self.notify.info("Deleting host %s: %s" % (host.hostUrl, host.hostDir))
shutil.rmtree(host.hostDir.toOsSpecific(), True) shutil.rmtree(host.hostDir.toOsSpecific(), True)
self.sendRequest('forget_package', host.hostUrl, '', '')
def freshenFile(self, host, fileSpec, localPathname): def freshenFile(self, host, fileSpec, localPathname):
""" Ensures that the localPathname is the most current version """ Ensures that the localPathname is the most current version
of the file defined by fileSpec, as offered by host. If not, 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())) self.notify.info("Deleting package %s: %s" % (package.packageName, package.getPackageDir()))
shutil.rmtree(package.getPackageDir().toOsSpecific(), True) 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): def __determineHostDir(self, hostDirBasename, hostUrl):
""" Hashes the host URL into a (mostly) unique directory """ Hashes the host URL into a (mostly) unique directory
string, which will be the root of the host's install tree. 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:: void P3DHost::
forget_package(P3DPackage *package, const string &alt_host) { forget_package(P3DPackage *package, const string &alt_host) {
string key = package->get_package_name() + "_" + package->get_package_version(); string key = package->get_package_name() + "_" + package->get_package_version();
nout << "Forgetting package " << key << "\n";
PackageMap &package_map = _packages[alt_host]; PackageMap &package_map = _packages[alt_host];

View File

@ -743,6 +743,28 @@ get_request() {
(*func)(data); (*func)(data);
} }
break; 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; break;
case P3D_RT_get_url: case P3D_RT_get_url:
if (request->_request._get_url._url != NULL) {
free((char *)request->_request._get_url._url); free((char *)request->_request._get_url._url);
request->_request._get_url._url = NULL; request->_request._get_url._url = NULL;
}
break; break;
case P3D_RT_notify: case P3D_RT_notify:
if (request->_request._notify._message != NULL) {
free((char *)request->_request._notify._message); free((char *)request->_request._notify._message);
request->_request._notify._message = NULL; 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; break;
} }
p3d_unref_delete(((P3DInstance *)request->_instance)); p3d_unref_delete(((P3DInstance *)request->_instance));
request->_instance = NULL; request->_instance = NULL;
delete request; delete request;
} }
@ -2245,6 +2287,27 @@ make_p3d_request(TiXmlElement *xrequest) {
request->_instance = NULL; request->_instance = NULL;
request->_request_type = P3D_RT_stop; 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 { } else {
nout << "Ignoring request of type " << rtype << "\n"; nout << "Ignoring request of type " << rtype << "\n";
} }

View File

@ -623,6 +623,8 @@ void P3DInstanceManager::
forget_host(P3DHost *host) { forget_host(P3DHost *host) {
const string &host_url = host->get_host_url(); 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 // Hmm, this is a memory leak. But we allow it to remain, since
// it's an unusual circumstance (uninstalling), and it's safer to // it's an unusual circumstance (uninstalling), and it's safer to
// leak than to risk a floating pointer. // leak than to risk a floating pointer.

View File

@ -1080,6 +1080,25 @@ py_request_func(PyObject *args) {
xrequest->SetAttribute("object_id", object_id); xrequest->SetAttribute("object_id", object_id);
write_xml(_pipe_write, &doc, nout); 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 { } else {
string message = string("Unsupported request type: ") + string(request_type); string message = string("Unsupported request type: ") + string(request_type);
PyErr_SetString(PyExc_ValueError, message.c_str()); PyErr_SetString(PyExc_ValueError, message.c_str());

View File

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

View File

@ -767,6 +767,7 @@ typedef enum {
P3D_RT_notify, P3D_RT_notify,
P3D_RT_refresh, P3D_RT_refresh,
P3D_RT_callback, P3D_RT_callback,
P3D_RT_forget_package
} P3D_request_type; } P3D_request_type;
/* Structures corresponding to the request types in the above enum. */ /* Structures corresponding to the request types in the above enum. */
@ -792,8 +793,9 @@ typedef struct {
} P3D_request_get_url; } P3D_request_get_url;
/* A general notification. This is just a message of some event /* A general notification. This is just a message of some event
having occurred within the Panda3D instance. It may be safely having occurred within the Panda3D instance. The core API will
ignored. automatically trigger a JavaScript callback based on this event.
It may be safely ignored by the application.
*/ */
typedef struct { typedef struct {
const char *_message; const char *_message;
@ -818,6 +820,19 @@ typedef struct {
void *_data; void *_data;
} P3D_request_callback; } 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 /* This is the overall structure that represents a single request. It
is returned by P3D_instance_get_request(). */ is returned by P3D_instance_get_request(). */
typedef struct { typedef struct {
@ -829,6 +844,7 @@ typedef struct {
P3D_request_notify _notify; P3D_request_notify _notify;
P3D_request_refresh _refresh; P3D_request_refresh _refresh;
P3D_request_callback _callback; P3D_request_callback _callback;
P3D_request_forget_package _forget_package;
} _request; } _request;
} P3D_request; } P3D_request;