Esempio n. 1
0
void CacheEntry::InvokeCallbacks()
{
  LOG(("CacheEntry::InvokeCallbacks BEGIN [this=%p]", this));

  mLock.AssertCurrentThreadOwns();

  do {
    if (mPreventCallbacks) {
      LOG(("CacheEntry::InvokeCallbacks END [this=%p] callbacks prevented!", this));
      return;
    }

    if (!mCallbacks.Count()) {
      LOG(("  no r/w callbacks"));
      break;
    }

    if (mHasMainThreadOnlyCallback && !NS_IsMainThread()) {
      nsRefPtr<nsRunnableMethod<CacheEntry> > event =
        NS_NewRunnableMethod(this, &CacheEntry::InvokeCallbacksMainThread);
      NS_DispatchToMainThread(event);
      LOG(("CacheEntry::InvokeCallbacks END [this=%p] dispatching to maintread", this));
      return;
    }

    nsCOMPtr<nsICacheEntryOpenCallback> callback = mCallbacks[0];
    mCallbacks.RemoveElementAt(0);

    if (!InvokeCallback(callback, false)) {
      mCallbacks.InsertElementAt(0, callback);
      LOG(("CacheEntry::InvokeCallbacks END [this=%p] callback bypassed", this));
      return;
    }
  } while (true);

  while (mReadOnlyCallbacks.Count()) {
    if (mHasMainThreadOnlyCallback && !NS_IsMainThread()) {
      nsRefPtr<nsRunnableMethod<CacheEntry> > event =
        NS_NewRunnableMethod(this, &CacheEntry::InvokeCallbacksMainThread);
      NS_DispatchToMainThread(event);
      LOG(("CacheEntry::InvokeCallbacks END [this=%p] dispatching to maintread", this));
      return;
    }

    nsCOMPtr<nsICacheEntryOpenCallback> callback = mReadOnlyCallbacks[0];
    mReadOnlyCallbacks.RemoveElementAt(0);

    if (!InvokeCallback(callback, true)) {
      // Didn't trigger, so we must stop
      mReadOnlyCallbacks.InsertElementAt(0, callback);
      break;
    }
  }

  if (!mCallbacks.Count() && !mReadOnlyCallbacks.Count())
    mHasMainThreadOnlyCallback = false;

  LOG(("CacheEntry::InvokeCallbacks END [this=%p]", this));
}
Esempio n. 2
0
 // if 
 void FileWatchImpl::OnDirectoryChangeNotification()
 {
     FILETIME fileLastWriteTime =  GetFileLastWriteTime(m_filename.GetString());
     if (fileLastWriteTime.dwHighDateTime != m_fileLastWriteTime.dwHighDateTime ||
         fileLastWriteTime.dwLowDateTime  != m_fileLastWriteTime.dwLowDateTime)
     {
         InvokeCallback();
         m_fileLastWriteTime = fileLastWriteTime;
     }
 }
Esempio n. 3
0
bool CacheEntry::InvokeCallbacks(bool aReadOnly)
{
  mLock.AssertCurrentThreadOwns();

  uint32_t i = 0;
  while (i < mCallbacks.Length()) {
    if (mPreventCallbacks) {
      LOG(("  callbacks prevented!"));
      return false;
    }

    if (!mIsDoomed && (mState == WRITING || mState == REVALIDATING)) {
      LOG(("  entry is being written/revalidated"));
      return false;
    }

    if (mCallbacks[i].mReadOnly != aReadOnly) {
      // Callback is not r/w or r/o, go to another one in line
      ++i;
      continue;
    }

    bool onCheckThread;
    nsresult rv = mCallbacks[i].OnCheckThread(&onCheckThread);

    if (NS_SUCCEEDED(rv) && !onCheckThread) {
      // Redispatch to the target thread
      nsRefPtr<nsRunnableMethod<CacheEntry> > event =
        NS_NewRunnableMethod(this, &CacheEntry::InvokeCallbacksLock);

      rv = mCallbacks[i].mTargetThread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
      if (NS_SUCCEEDED(rv)) {
        LOG(("  re-dispatching to target thread"));
        return false;
      }
    }

    Callback callback = mCallbacks[i];
    mCallbacks.RemoveElementAt(i);

    if (NS_SUCCEEDED(rv) && !InvokeCallback(callback)) {
      // Callback didn't fire, put it back and go to another one in line.
      // Only reason InvokeCallback returns false is that onCacheEntryCheck
      // returns RECHECK_AFTER_WRITE_FINISHED.  If we would stop the loop, other
      // readers or potential writers would be unnecessarily kept from being
      // invoked.
      size_t pos = std::min(mCallbacks.Length(), static_cast<size_t>(i));
      mCallbacks.InsertElementAt(pos, callback);
      ++i;
    }
  }

  return true;
}
void CoreClrFuncInvokeContext::TaskCompleteSynchronous(void* result, int resultType, int taskState, Handle<v8::Value> callback)
{
	DBG("CoreClrFuncInvokeContext::TaskCompleteSynchronous");

	CoreClrFuncInvokeContext* context = new CoreClrFuncInvokeContext(callback, NULL);

	context->resultData = result;
	context->resultType = resultType;
	context->taskState = taskState;

	InvokeCallback(context);
}
Esempio n. 5
0
PLUGIN_EXPORT bool PLUGIN_CALL OnPublicCall(AMX *amx, const char *name, cell *params, cell *retval)
{
    bool foundFunction = false;
    auto result = InvokeCallback(amx, name, params, foundFunction);
    if (foundFunction)
    {
        if (retval) *retval = result;
        if (ShouldCancelCallback(name, result)) {
            return false;
        }
    }
    bool success = false;
    auto hook = CallHookedCallback(amx, name, params, success);
    if (success)
    {
        if (retval) *retval = hook[0];
        if (hook[1]) return false;
    }
    return true;
}
Esempio n. 6
0
bool CacheEntry::InvokeCallback(Callback & aCallback)
{
  LOG(("CacheEntry::InvokeCallback [this=%p, state=%s, cb=%p]",
    this, StateString(mState), aCallback.mCallback.get()));

  mLock.AssertCurrentThreadOwns();

  // When this entry is doomed we want to notify the callback any time
  if (!mIsDoomed) {
    // When we are here, the entry must be loaded from disk
    MOZ_ASSERT(mState > LOADING);

    if (mState == WRITING || mState == REVALIDATING) {
      // Prevent invoking other callbacks since one of them is now writing
      // or revalidating this entry.  No consumers should get this entry
      // until metadata are filled with values downloaded from the server
      // or the entry revalidated and output stream has been opened.
      LOG(("  entry is being written/revalidated, callback bypassed"));
      return false;
    }

    // mRecheckAfterWrite flag already set means the callback has already passed
    // the onCacheEntryCheck call. Until the current write is not finished this
    // callback will be bypassed.
    if (!aCallback.mRecheckAfterWrite) {

      if (!aCallback.mReadOnly) {
        if (mState == EMPTY) {
          // Advance to writing state, we expect to invoke the callback and let
          // it fill content of this entry.  Must set and check the state here
          // to prevent more then one
          mState = WRITING;
          LOG(("  advancing to WRITING state"));
        }

        if (!aCallback.mCallback) {
          // We can be given no callback only in case of recreate, it is ok
          // to advance to WRITING state since the caller of recreate is expected
          // to write this entry now.
          return true;
        }
      }

      if (mState == READY) {
        // Metadata present, validate the entry
        uint32_t checkResult;
        {
          // mayhemer: TODO check and solve any potential races of concurent OnCacheEntryCheck
          mozilla::MutexAutoUnlock unlock(mLock);

          nsresult rv = aCallback.mCallback->OnCacheEntryCheck(
            this, nullptr, &checkResult);
          LOG(("  OnCacheEntryCheck: rv=0x%08x, result=%d", rv, checkResult));

          if (NS_FAILED(rv))
            checkResult = ENTRY_NOT_WANTED;
        }

        aCallback.mRevalidating = checkResult == ENTRY_NEEDS_REVALIDATION;

        switch (checkResult) {
        case ENTRY_WANTED:
          // Nothing more to do here, the consumer is responsible to handle
          // the result of OnCacheEntryCheck it self.
          // Proceed to callback...
          break;

        case RECHECK_AFTER_WRITE_FINISHED:
          LOG(("  consumer will check on the entry again after write is done"));
          // The consumer wants the entry to complete first.
          aCallback.mRecheckAfterWrite = true;
          break;

        case ENTRY_NEEDS_REVALIDATION:
          LOG(("  will be holding callbacks until entry is revalidated"));
          // State is READY now and from that state entry cannot transit to any other
          // state then REVALIDATING for which cocurrency is not an issue.  Potentially
          // no need to lock here.
          mState = REVALIDATING;
          break;

        case ENTRY_NOT_WANTED:
          LOG(("  consumer not interested in the entry"));
          // Do not give this entry to the consumer, it is not interested in us.
          aCallback.mNotWanted = true;
          break;
        }
      }
    }
  }

  if (aCallback.mCallback) {
    if (!mIsDoomed && aCallback.mRecheckAfterWrite) {
      // If we don't have data and the callback wants a complete entry,
      // don't invoke now.
      bool bypass = !mHasData;
      if (!bypass && NS_SUCCEEDED(mFileStatus)) {
        int64_t _unused;
        bypass = !mFile->DataSize(&_unused);
      }

      if (bypass) {
        LOG(("  bypassing, entry data still being written"));
        return false;
      }

      // Entry is complete now, do the check+avail call again
      aCallback.mRecheckAfterWrite = false;
      return InvokeCallback(aCallback);
    }

    mozilla::MutexAutoUnlock unlock(mLock);
    InvokeAvailableCallback(aCallback);
  }

  return true;
}
void PerformSearch(JNIEnv *env, jobject obj, jobject callback, std::wstring searchText, std::list<std::wstring>& patterns,int maximumResults, jobject monitor)
{

	ADODB::_ConnectionPtr connection = NULL;
	ADODB::_RecordsetPtr recordset = NULL;
	try {
		HRESULT hr = ::CoInitialize(NULL);
		if (!SUCCEEDED(hr))
			return;

		hr = connection.CreateInstance(__uuidof(ADODB::Connection));
		if (!SUCCEEDED(hr))
			return;

		hr = recordset.CreateInstance(__uuidof(ADODB::Recordset));
		if (!SUCCEEDED(hr))
			return;

		connection->CursorLocation = ADODB::adUseClient;
		hr = connection->Open(L"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';", L"", L"", ADODB::adConnectUnspecified);
		if (!SUCCEEDED(hr))
			return;

		
		searchText = ReplaceCharWithString(searchText, '\'', L"''");

		std::wstring filenameMatcher = searchText;
		filenameMatcher = ReplaceCharWithString(filenameMatcher, '%', L"\\%");
		filenameMatcher = ReplaceCharWithString(filenameMatcher, '*', L"%");
		
		// see FREETEXT http://msdn.microsoft.com/en-us/library/bb231268(v=vs.85).aspx
		// see CONTAINS http://msdn.microsoft.com/en-us/library/bb231270(v=vs.85).aspx

		std::wstring query = L"SELECT TOP ";
		query += IntToString(maximumResults);
		query += L" System.ItemPathDisplay from SystemIndex WHERE ";
		// limit to documents, pictures and video
		query += L"(System.Kind = 'document' or System.Kind = 'picture' or System.Kind = 'video' or System.Kind is null) AND ";
		// content search
		query += L"(FREETEXT('\"";
		query += searchText;
		query += L"\"') OR ";
		// filename search
		query += L"(System.ItemName LIKE '%";
		query += filenameMatcher;
		query += L"%'))";

		if (patterns.size() > 0) {
			bool hasFilenameSearch = true;
			std::wstring anyFile(L"*");

			for(std::list<std::wstring>::iterator iterator = patterns.begin(); iterator != patterns.end(); iterator++) {
				std::wstring pattern = *iterator;
				if (pattern == anyFile) {
					hasFilenameSearch = false;
					break;
				}
			}
			if (hasFilenameSearch) {
				query += L" AND (";
				for(std::list<std::wstring>::iterator iterator = patterns.begin(); iterator != patterns.end(); iterator++) {
					std::wstring pattern = *iterator;
					if (pattern.size() == 0) {
						continue;
					}
					pattern = ReplaceCharWithString(pattern, '*', L"%");
					if (iterator != patterns.begin()) {
						query += L" OR ";
					}
					query += L"(System.ItemName LIKE '";
					if (pattern[0] != '%') {
						query += L"%";
					}
					query += pattern;
					query += L"')";
				}
				query += L")";
			}
		}
		
		//std::cout << "Query:\n";
		//std::cout << query;
		//std::cout << "\n";
		//std::cout << std::flush;
		
		hr = recordset->Open(query.c_str(), connection.GetInterfacePtr(), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText);
		if (!SUCCEEDED(hr)) {
			std::cout << "Open Failed\n" << std::flush;
			return;
		}

		int count = maximumResults;
		
		
		while(!recordset->ADOEOF)
		{
			_variant_t var = recordset->Fields->GetItem(L"System.ItemPathDisplay")->GetValue();
			std::wstring filename = (const wchar_t*)_bstr_t(var.bstrVal);
			InvokeCallback(env, obj, callback, filename);

			if (IsProgressMonitorCancelled(env,monitor)) {
				break;
			}

			if (--count < 0) {
				break;
			}

			hr = recordset->MoveNext();
			if (!SUCCEEDED(hr)) {
				std::cout << "Move Next Failed\n" << std::flush;
				break;
			}
		}
	} catch (_com_error &e)	{
		_tprintf(_T("\tCOM Error code = %08lx\n"), e.Error());
	}


	if (recordset != NULL && recordset->State == ADODB::adStateOpen)
		recordset->Close();
	if (connection != NULL && connection->State == ADODB::adStateOpen)
		connection->Close();   

	::CoUninitialize();
}