use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.
the class CoreImpl method stopSupport.
void stopSupport(final boolean for_restart, final boolean apply_updates) throws CoreException {
Logger.setClosing();
AEDiagnostics.flushPendingLogs();
boolean wait_and_return = false;
try {
this_mon.enter();
if (stopped) {
// ensure config is saved as there may be pending changes to persist and we've got here
// via a shutdown hook
COConfigurationManager.save();
wait_and_return = true;
} else {
stopped = true;
if (!started) {
Logger.log(new LogEvent(LOGID, "Core not started"));
if (AEDiagnostics.isDirty()) {
AEDiagnostics.markClean();
}
stopping_sem.releaseForever();
return;
}
}
} finally {
this_mon.exit();
}
if (wait_and_return) {
Logger.log(new LogEvent(LOGID, "Waiting for stop to complete"));
stopping_sem.reserve();
return;
}
final AtomicLong last_progress = new AtomicLong(SystemTime.getMonotonousTime());
SimpleTimer.addEvent("ShutFail", SystemTime.getOffsetTime(60 * 1000), new TimerEventPerformer() {
boolean die_die_die;
@Override
public void perform(TimerEvent event) {
last_progress.set(SystemTime.getMonotonousTime());
while (SystemTime.getMonotonousTime() - last_progress.get() < 30 * 1000) {
try {
Thread.sleep(5000);
} catch (Throwable e) {
}
}
AEDiagnostics.dumpThreads();
if (die_die_die) {
Debug.out("Shutdown blocked, force exiting");
stopping_sem.releaseForever();
if (for_restart) {
ClientRestarterFactory.create(CoreImpl.this).restart(false);
} else if (apply_updates) {
if (getPluginManager().getDefaultPluginInterface().getUpdateManager().getInstallers().length > 0) {
ClientRestarterFactory.create(CoreImpl.this).restart(true);
}
}
if (ca_shutdown_computer_after_stop) {
if (apply_updates) {
// best we can do here is wait a while for updates to be applied
try {
Thread.sleep(10 * 1000);
} catch (Throwable e) {
}
}
try {
PlatformManagerFactory.getPlatformManager().shutdown(PlatformManager.SD_SHUTDOWN);
} catch (Throwable e) {
Debug.out("PlatformManager: shutdown failed", e);
}
}
SESecurityManager.exitVM(0);
}
die_die_die = true;
SimpleTimer.addEvent("ShutFail", SystemTime.getOffsetTime(30 * 1000), this);
}
});
List sync_listeners = new ArrayList();
List async_listeners = new ArrayList();
Iterator it = lifecycle_listeners.iterator();
while (it.hasNext()) {
CoreLifecycleListener l = (CoreLifecycleListener) it.next();
if (l.syncInvokeRequired()) {
sync_listeners.add(l);
} else {
async_listeners.add(l);
}
}
try {
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Invoking synchronous 'stopping' listeners"));
for (int i = 0; i < sync_listeners.size(); i++) {
try {
((CoreLifecycleListener) sync_listeners.get(i)).stopping(this);
} catch (Throwable e) {
Debug.printStackTrace(e);
}
last_progress.set(SystemTime.getMonotonousTime());
}
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Invoking asynchronous 'stopping' listeners"));
// in case something hangs during listener notification (e.g. version check server is down
// and the instance manager tries to obtain external address) we limit overall dispatch
// time to 10 seconds
ListenerManager.dispatchWithTimeout(async_listeners, new ListenerManagerDispatcher() {
@Override
public void dispatch(Object listener, int type, Object value) {
((CoreLifecycleListener) listener).stopping(CoreImpl.this);
last_progress.set(SystemTime.getMonotonousTime());
}
}, 10 * 1000);
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Waiting for quiescence pre gm stop"));
NonDaemonTaskRunner.waitUntilIdle();
last_progress.set(SystemTime.getMonotonousTime());
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Stopping global manager"));
if (global_manager != null) {
global_manager.stopGlobalManager();
}
last_progress.set(SystemTime.getMonotonousTime());
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Invoking synchronous 'stopped' listeners"));
for (int i = 0; i < sync_listeners.size(); i++) {
try {
((CoreLifecycleListener) sync_listeners.get(i)).stopped(this);
} catch (Throwable e) {
Debug.printStackTrace(e);
}
last_progress.set(SystemTime.getMonotonousTime());
}
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Invoking asynchronous 'stopped' listeners"));
ListenerManager.dispatchWithTimeout(async_listeners, new ListenerManagerDispatcher() {
@Override
public void dispatch(Object listener, int type, Object value) {
((CoreLifecycleListener) listener).stopped(CoreImpl.this);
last_progress.set(SystemTime.getMonotonousTime());
}
}, 10 * 1000);
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Waiting for quiescence post gm stop"));
NonDaemonTaskRunner.waitUntilIdle();
last_progress.set(SystemTime.getMonotonousTime());
// shut down diags - this marks the shutdown as tidy and saves the config
AEDiagnostics.markClean();
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Stop operation completes"));
if (apply_updates && getPluginManager().getDefaultPluginInterface().getUpdateManager().getInstallers().length > 0) {
ClientRestarterFactory.create(this).restart(true);
}
if (System.getProperty("skip.shutdown.nondeamon.check", "0").equals("1")) {
return;
}
try {
Class c = Class.forName("sun.awt.AWTAutoShutdown");
if (c != null) {
c.getMethod("notifyToolkitThreadFree", new Class[] {}).invoke(null, new Object[] {});
}
} catch (Throwable t) {
}
if (ca_shutdown_computer_after_stop) {
if (apply_updates) {
// best we can do here is wait a while for updates to be applied
try {
Thread.sleep(10 * 1000);
} catch (Throwable e) {
}
}
try {
PlatformManagerFactory.getPlatformManager().shutdown(PlatformManager.SD_SHUTDOWN);
} catch (Throwable e) {
Debug.out("PlatformManager: shutdown failed", e);
}
}
try {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while (tg.getParent() != null) {
tg = tg.getParent();
}
Thread[] threads = new Thread[tg.activeCount() + 1024];
tg.enumerate(threads, true);
boolean bad_found = false;
for (int i = 0; i < threads.length; i++) {
Thread t = threads[i];
if (t != null && t.isAlive() && t != Thread.currentThread() && !t.isDaemon() && !AEThread2.isOurThread(t)) {
bad_found = true;
break;
}
}
if (bad_found) {
new AEThread2("VMKiller", true) {
@Override
public void run() {
try {
Thread.sleep(10 * 1000);
ThreadGroup tg = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[tg.activeCount() + 1024];
tg.enumerate(threads, true);
String bad_found = "";
for (int i = 0; i < threads.length; i++) {
Thread t = threads[i];
if (t != null && t.isAlive() && !t.isDaemon() && !AEThread2.isOurThread(t)) {
String details = t.getName();
StackTraceElement[] trace = t.getStackTrace();
if (trace.length > 0) {
details += "[";
for (int j = 0; j < trace.length; j++) {
details += (j == 0 ? "" : ",") + trace[j];
}
details += "]";
}
bad_found += (bad_found.length() == 0 ? "" : ", ") + details;
}
}
Debug.out("Non-daemon thread(s) found: '" + bad_found + "' - force closing VM");
SESecurityManager.exitVM(0);
} catch (Throwable e) {
}
}
}.start();
}
} catch (Throwable e) {
}
} finally {
stopping_sem.releaseForever();
}
}
use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.
the class CoreImpl method executeScript.
void executeScript(String script, String action, boolean download_trigger) {
String script_type = "";
if (script.length() >= 10 && script.substring(0, 10).toLowerCase(Locale.US).startsWith("javascript")) {
int p1 = script.indexOf('(');
int p2 = script.lastIndexOf(')');
if (p1 != -1 && p2 != -1) {
script = script.substring(p1 + 1, p2).trim();
if (script.startsWith("\"") && script.endsWith("\"")) {
script = script.substring(1, script.length() - 1);
}
// allow people to escape " if it makes them feel better
script = script.replaceAll("\\\\\"", "\"");
script_type = ScriptProvider.ST_JAVASCRIPT;
}
}
File script_file = null;
if (script_type == "") {
script_file = new File(script.trim());
if (!script_file.isFile()) {
Logger.log(new LogEvent(LOGID, "Script failed to run - '" + script_file + "' isn't a valid script file"));
Debug.out("Invalid script: " + script_file);
return;
}
}
try {
boolean close_vuze = action.equals("RunScriptAndClose");
if (!close_vuze) {
// assume script might implement a sleep
announceAll(true);
}
if (script_file != null) {
getPluginManager().getDefaultPluginInterface().getUtilities().createProcess(script_file.getAbsolutePath());
} else {
boolean provider_found = false;
List<ScriptProvider> providers = CoreFactory.getSingleton().getPluginManager().getDefaultPluginInterface().getUtilities().getScriptProviders();
for (ScriptProvider p : providers) {
if (p.getScriptType() == script_type) {
provider_found = true;
Map<String, Object> bindings = new HashMap<>();
String intent = "shutdown" + "(\"" + action + "\")";
bindings.put("intent", intent);
bindings.put("is_downloading_complete", download_trigger);
p.eval(script, bindings);
}
}
if (!provider_found) {
if (!js_plugin_install_tried) {
js_plugin_install_tried = true;
PluginUtils.installJavaScriptPlugin();
}
}
}
if (close_vuze) {
requestStop();
}
} catch (Throwable e) {
Logger.log(new LogAlert(true, LogAlert.AT_ERROR, "Script failed to run - '" + script + "'", e));
Debug.out("Invalid script: " + script, e);
}
}
use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.
the class GlobalManagerImpl method addDownloadManager.
protected DownloadManager addDownloadManager(DownloadManager download_manager, boolean save, boolean notifyListeners) {
if (!isStopping) {
// make sure we have existing ones loaded so that existing check works
loadExistingTorrentsNow(false);
try {
managers_mon.enter();
int existing_index = managers_cow.indexOf(download_manager);
if (existing_index != -1) {
DownloadManager existing = managers_cow.get(existing_index);
download_manager.destroy(true);
return (existing);
}
DownloadManagerStats dm_stats = download_manager.getStats();
HashWrapper hashwrapper = null;
try {
TOTorrent torrent = download_manager.getTorrent();
if (torrent != null) {
hashwrapper = torrent.getHashWrapper();
}
} catch (Exception e1) {
}
Map save_download_state = (Map) saved_download_manager_state.remove(hashwrapper);
long saved_data_bytes_downloaded = 0;
long saved_data_bytes_uploaded = 0;
long saved_discarded = 0;
long saved_hashfails = 0;
long saved_SecondsDownloading = 0;
long saved_SecondsOnlySeeding = 0;
if (save_download_state != null) {
int maxDL = save_download_state.get("maxdl") == null ? 0 : ((Long) save_download_state.get("maxdl")).intValue();
int maxUL = save_download_state.get("maxul") == null ? 0 : ((Long) save_download_state.get("maxul")).intValue();
Long lDownloaded = (Long) save_download_state.get("downloaded");
Long lUploaded = (Long) save_download_state.get("uploaded");
Long lCompletedBytes = (Long) save_download_state.get("completedbytes");
Long lDiscarded = (Long) save_download_state.get("discarded");
// old method, number of fails
Long lHashFailsCount = (Long) save_download_state.get("hashfails");
// new method, bytes failed
Long lHashFailsBytes = (Long) save_download_state.get("hashfailbytes");
// migrated to downloadstate in 2403
Long nbUploads = (Long) save_download_state.get("uploads");
if (nbUploads != null) {
// migrate anything other than the default value of 4
int maxUploads = nbUploads.intValue();
if (maxUploads != 4) {
// value if the stored value is non-default and the state one is
if (download_manager.getMaxUploads() == 4) {
download_manager.setMaxUploads(maxUploads);
}
}
}
dm_stats.setDownloadRateLimitBytesPerSecond(maxDL);
dm_stats.setUploadRateLimitBytesPerSecond(maxUL);
if (lCompletedBytes != null) {
dm_stats.setDownloadCompletedBytes(lCompletedBytes.longValue());
}
if (lDiscarded != null) {
saved_discarded = lDiscarded.longValue();
}
if (lHashFailsBytes != null) {
saved_hashfails = lHashFailsBytes.longValue();
} else if (lHashFailsCount != null) {
TOTorrent torrent = download_manager.getTorrent();
if (torrent != null) {
saved_hashfails = lHashFailsCount.longValue() * torrent.getPieceLength();
}
}
Long lPosition = (Long) save_download_state.get("position");
// 2.2.0.1 - category moved to downloadstate - this here for
// migration purposes
String sCategory = null;
if (save_download_state.containsKey("category")) {
try {
sCategory = new String((byte[]) save_download_state.get("category"), Constants.DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
Debug.printStackTrace(e);
}
}
if (sCategory != null) {
Category cat = CategoryManager.getCategory(sCategory);
if (cat != null)
download_manager.getDownloadState().setCategory(cat);
}
download_manager.requestAssumedCompleteMode();
if (lDownloaded != null && lUploaded != null) {
boolean bCompleted = download_manager.isDownloadComplete(false);
long lUploadedValue = lUploaded.longValue();
long lDownloadedValue = lDownloaded.longValue();
if (bCompleted && (lDownloadedValue == 0)) {
// Gudy : I say if the torrent is complete, let's simply set downloaded
// to size in order to see a meaningfull share-ratio
// Gudy : Bypass this horrible hack, and I don't care of first priority seeding...
/*
if (lDownloadedValue != 0 && ((lUploadedValue * 1000) / lDownloadedValue < minQueueingShareRatio) )
lUploadedValue = ( download_manager.getSize()+999) * minQueueingShareRatio / 1000;
*/
// Parg: quite a few users have complained that they want "open-for-seeding" torrents to
// have an infinite share ratio for seeding rules (i.e. so they're not first priority)
int dl_copies = COConfigurationManager.getIntParameter("StartStopManager_iAddForSeedingDLCopyCount");
lDownloadedValue = download_manager.getSize() * dl_copies;
download_manager.getDownloadState().setFlag(DownloadManagerState.FLAG_ONLY_EVER_SEEDED, true);
}
saved_data_bytes_downloaded = lDownloadedValue;
saved_data_bytes_uploaded = lUploadedValue;
}
if (lPosition != null)
download_manager.setPosition(lPosition.intValue());
// no longer needed code
// else if (dm_stats.getDownloadCompleted(false) < 1000)
// dm.setPosition(bCompleted ? numCompleted : numDownloading);
Long lSecondsDLing = (Long) save_download_state.get("secondsDownloading");
if (lSecondsDLing != null) {
saved_SecondsDownloading = lSecondsDLing.longValue();
}
Long lSecondsOnlySeeding = (Long) save_download_state.get("secondsOnlySeeding");
if (lSecondsOnlySeeding != null) {
saved_SecondsOnlySeeding = lSecondsOnlySeeding.longValue();
}
Long already_allocated = (Long) save_download_state.get("allocated");
if (already_allocated != null && already_allocated.intValue() == 1) {
download_manager.setDataAlreadyAllocated(true);
}
Long creation_time = (Long) save_download_state.get("creationTime");
if (creation_time != null) {
long ct = creation_time.longValue();
if (ct < SystemTime.getCurrentTime()) {
download_manager.setCreationTime(ct);
}
}
} else {
if (dm_stats.getDownloadCompleted(false) == 1000) {
int dl_copies = COConfigurationManager.getIntParameter("StartStopManager_iAddForSeedingDLCopyCount");
saved_data_bytes_downloaded = download_manager.getSize() * dl_copies;
}
}
dm_stats.restoreSessionTotals(saved_data_bytes_downloaded, saved_data_bytes_uploaded, saved_discarded, saved_hashfails, saved_SecondsDownloading, saved_SecondsOnlySeeding);
boolean isCompleted = download_manager.isDownloadComplete(false);
if (download_manager.getPosition() == -1) {
int endPosition = 0;
for (int i = 0; i < managers_cow.size(); i++) {
DownloadManager dm = managers_cow.get(i);
boolean dmIsCompleted = dm.isDownloadComplete(false);
if (dmIsCompleted == isCompleted)
endPosition++;
}
download_manager.setPosition(endPosition + 1);
}
// Even though when the DownloadManager was created, onlySeeding was
// most likely set to true for completed torrents (via the Initializer +
// readTorrent), there's a chance that the torrent file didn't have the
// resume data. If it didn't, but we marked it as complete in our
// downloads config file, we should set to onlySeeding
download_manager.requestAssumedCompleteMode();
List<DownloadManager> new_download_managers = new ArrayList<>(managers_cow);
new_download_managers.add(download_manager);
managers_cow = new_download_managers;
TOTorrent torrent = download_manager.getTorrent();
if (torrent != null) {
try {
manager_map.put(new HashWrapper(torrent.getHash()), download_manager);
} catch (TOTorrentException e) {
Debug.printStackTrace(e);
}
}
// flag set, to prevent them being moved.
if (COConfigurationManager.getBooleanParameter("Set Completion Flag For Completed Downloads On Start")) {
// ones yet.
if (download_manager.isDownloadComplete(true)) {
download_manager.getDownloadState().setFlag(DownloadManagerState.FLAG_MOVE_ON_COMPLETION_DONE, true);
}
}
if (notifyListeners) {
listeners_and_event_listeners.dispatch(LDT_MANAGER_ADDED, download_manager);
taggable_life_manager.taggableCreated(download_manager);
if (host_support != null) {
host_support.torrentAdded(download_manager.getTorrentFileName(), download_manager.getTorrent());
}
}
download_manager.addListener(this);
if (save_download_state != null) {
Long lForceStart = (Long) save_download_state.get("forceStart");
if (lForceStart == null) {
Long lStartStopLocked = (Long) save_download_state.get("startStopLocked");
if (lStartStopLocked != null) {
lForceStart = lStartStopLocked;
}
}
if (lForceStart != null) {
if (lForceStart.intValue() == 1) {
download_manager.setForceStart(true);
}
}
}
} finally {
managers_mon.exit();
}
if (save) {
saveDownloads(false);
}
return (download_manager);
} else {
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Tried to add a DownloadManager after shutdown of GlobalManager."));
return (null);
}
}
use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.
the class GlobalManagerImpl method checkForceStart.
protected void checkForceStart(boolean known_to_exist) {
boolean exists;
if (known_to_exist) {
exists = true;
} else {
exists = false;
if (force_start_non_seed_exists) {
List managers = managers_cow;
for (int i = 0; i < managers.size(); i++) {
DownloadManager dm = (DownloadManager) managers.get(i);
if (dm.isForceStart() && dm.getState() == DownloadManager.STATE_DOWNLOADING) {
exists = true;
break;
}
}
}
}
if (exists != force_start_non_seed_exists) {
force_start_non_seed_exists = exists;
Logger.log(new LogEvent(LOGID, "Force start download " + (force_start_non_seed_exists ? "exists" : "doesn't exist") + ", modifying download weighting"));
// System.out.println( "force_start_exists->" + force_start_non_seed_exists );
PeerControlSchedulerFactory.overrideWeightedPriorities(force_start_non_seed_exists);
}
}
use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.
the class CacheFileManagerImpl method allocateCacheSpace.
/**
* allocates space but does NOT add it to the cache list due to synchronization issues. Basically
* the caller mustn't hold their monitor when calling allocate, as a flush may result in one or more
* other files being flushed which results in their monitor being taken, and we've got an A->B and
* B->A classic deadlock situation. However, we must keep the file's cache and our cache in step.
* It is not acceptable to have an entry inserted into our records but not in the file's as this
* then screws up the flush algorithm (which assumes that if it finds an entry in our list, a flush
* of that file is guaranteed to release space). Therefore we add the cache entry in addCacheSpace
* so that the caller can safely do this while synchronised firstly on its monitor and then we can
* sync on our. Hence we only ever get A->B monitor grabs which won't deadlock
* @param file
* @param buffer
* @param file_position
* @param length
* @return
* @throws CacheFileManagerException
*/
protected CacheEntry allocateCacheSpace(int entry_type, CacheFileWithCache file, DirectByteBuffer buffer, long file_position, int length) throws CacheFileManagerException {
boolean ok = false;
boolean log = false;
while (!ok) {
// musn't invoke synchronised CacheFile methods while holding manager lock as this
// can cause deadlocks (as CacheFile calls manager methods with locks)
CacheEntry oldest_entry = null;
try {
this_mon.enter();
if (length < cache_space_free || cache_space_free == cache_size) {
ok = true;
} else {
oldest_entry = (CacheEntry) cache_entries.keySet().iterator().next();
}
} finally {
this_mon.exit();
}
if (!ok) {
log = true;
long old_free = cache_space_free;
CacheFileWithCache oldest_file = oldest_entry.getFile();
try {
oldest_file.flushCache(oldest_entry.getFilePosition(), true, cache_minimum_free_size);
} catch (CacheFileManagerException e) {
if (oldest_file != file) {
oldest_file.setPendingException(e);
} else {
throw (e);
}
}
long flushed = cache_space_free - old_free;
if (Logger.isEnabled()) {
TOTorrentFile tf = file.getTorrentFile();
TOTorrent torrent = tf == null ? null : tf.getTorrent();
Logger.log(new LogEvent(torrent, LOGID, "DiskCache: cache full, flushed " + flushed + " from " + oldest_file.getName()));
}
if (flushed == 0) {
try {
this_mon.enter();
if (cache_entries.size() > 0 && (CacheEntry) cache_entries.keySet().iterator().next() == oldest_entry) {
throw (new CacheFileManagerException(null, "Cache inconsistent: 0 flushed"));
}
} finally {
this_mon.exit();
}
}
}
}
CacheEntry entry = new CacheEntry(entry_type, file, buffer, file_position, length);
if (log && Logger.isEnabled()) {
TOTorrentFile tf = file.getTorrentFile();
TOTorrent torrent = tf == null ? null : tf.getTorrent();
Logger.log(new LogEvent(torrent, LOGID, "DiskCache: cr=" + cache_bytes_read + ",cw=" + cache_bytes_written + ",fr=" + file_bytes_read + ",fw=" + file_bytes_written));
}
return (entry);
}
Aggregations