static int powernet_check_comm_lost(UPSINFO *ups) { struct timeval now; static struct timeval prev; struct snmp_ups_internal_data *Sid = (struct snmp_ups_internal_data *)ups->driver_internal_data; struct snmp_session *s = &Sid->session; powernet_mib_t *data = (powernet_mib_t *)Sid->MIB; int ret = 1; /* * Check the Ethernet COMMLOST first, then check the * Web/SNMP->UPS serial COMMLOST. */ data->upsComm = NULL; if (powernet_mib_mgr_get_upsComm(s, &(data->upsComm)) < 0 || (data->upsComm && data->upsComm->__upsCommStatus == 2)) { if (!ups->is_commlost()) { generate_event(ups, CMDCOMMFAILURE); ups->set_commlost(); gettimeofday(&prev, NULL); } /* Log an event every 10 minutes */ gettimeofday(&now, NULL); if (TV_DIFF_MS(prev, now) >= 10*60*1000) { log_event(ups, event_msg[CMDCOMMFAILURE].level, event_msg[CMDCOMMFAILURE].msg); prev = now; } ret = 0; } else if (ups->is_commlost()) { generate_event(ups, CMDCOMMOK); ups->clear_commlost(); } if (data->upsComm) free(data->upsComm); return ret; }
void dispt(timeval start, timeval end, int cnt, const char *name) { long tot = TV_DIFF_MS(start, end); cout << "time for " << name << " (" << cnt << " decomps): " << tot << "ms, " << tot/(float)cnt << "ms/decomp" << endl; }
/* Note this routine MUST be called with the UPS write lock held! */ void UPSlinkCheck(UPSINFO *ups) { struct timeval now, prev, start; static int linkcheck = FALSE; if (linkcheck) return; linkcheck = TRUE; /* prevent recursion */ tcflush(ups->fd, TCIOFLUSH); if (strcmp(smart_poll('Y', ups), "SM") == 0) { linkcheck = FALSE; ups->clear_commlost(); return; } write_unlock(ups); gettimeofday(&start, NULL); prev = start; tcflush(ups->fd, TCIOFLUSH); while (strcmp(smart_poll('Y', ups), "SM") != 0) { /* Declare commlost only if COMMLOST_TIMEOUT_MS has expired */ gettimeofday(&now, NULL); if (TV_DIFF_MS(start, now) >= COMMLOST_TIMEOUT_MS) { /* Generate commlost event if we've not done so yet */ if (!ups->is_commlost()) { ups->set_commlost(); generate_event(ups, CMDCOMMFAILURE); prev = now; } /* Log an event every 10 minutes */ if (TV_DIFF_MS(prev, now) >= 10*60*1000) { log_event(ups, event_msg[CMDCOMMFAILURE].level, event_msg[CMDCOMMFAILURE].msg); prev = now; } } /* * This sleep should not be necessary since the smart_poll() * routine normally waits TIMER_FAST (1) seconds. However, * in case the serial port is broken and generating spurious * characters, we sleep to reduce CPU consumption. */ sleep(1); tcflush(ups->fd, TCIOFLUSH); } write_lock(ups); if (ups->is_commlost()) { ups->clear_commlost(); generate_event(ups, CMDCOMMOK); } linkcheck = FALSE; }
DWORD WINAPI BalloonMgr::Thread(LPVOID param) { BalloonMgr *_this = (BalloonMgr*)param; HANDLE handles[] = {_this->_event, _this->_timer}; LARGE_INTEGER timeout; struct timeval now; DWORD index; long diff; while (1) { // Wait for timeout or new balloon request index = WaitForMultipleObjects( ARRAY_SIZE(handles), handles, false, INFINITE); // Exit if we've been asked to do so if (_this->_exit) break; switch (index) { // New balloon request has arrived case WAIT_OBJECT_0 + 0: _this->lock(); if (!_this->_active) { // No balloon active: Post new balloon immediately if (!_this->_pending.empty()) { _this->post(); _this->_active = true; } } else { // A balloon is active: Shorten timer to minimum CancelWaitableTimer(_this->_timer); gettimeofday(&now, NULL); diff = TV_DIFF_MS(_this->_time, now); if (diff >= MIN_TIMEOUT) { // Min timeout already expired timeout.QuadPart = -1; } else { // Wait enough additional time to meet minimum timeout timeout.QuadPart = -((MIN_TIMEOUT - diff) * 10000); } SetWaitableTimer(_this->_timer, &timeout, 0, NULL, NULL, false); } _this->unlock(); break; // Timeout ocurred case WAIT_OBJECT_0 + 1: _this->lock(); // Clear active balloon _this->clear(); // Post next balloon if there is one if (!_this->_pending.empty()) { _this->post(); _this->_active = true; } else { _this->_active = false; } _this->unlock(); break; default: // Should never happen...but if it does, sleep a bit to prevent // spinning. Sleep(1000); break; } } }