Example #1
0
	SLONG Database::SharedCounter::generate(thread_db* tdbb, ULONG space, ULONG prefetch)
	{
		fb_assert(space < TOTAL_ITEMS);
		ValueCache* const counter = &m_counters[space];

		if (m_localOnly)
		{
			SLONG result = 0;
			while ( !(result = (SLONG) ++counter->curVal) )
				;
			return result;
		}

		Database* const dbb = tdbb->getDatabase();
		SyncLockGuard guard(&dbb->dbb_sh_counter_sync, SYNC_EXCLUSIVE, "Database::SharedCounter::generate");

		if (!counter->lock)
		{
			Lock* const lock =
				FB_NEW_RPT(*dbb->dbb_permanent, 0) Lock(tdbb, sizeof(SLONG), LCK_shared_counter);
			counter->lock = lock;
			lock->lck_key.lck_long = space;
			LCK_lock(tdbb, lock, LCK_PW, LCK_WAIT);
		}

		SLONG result = (SLONG) ++counter->curVal;

		if (result > counter->maxVal)
		{
			LCK_convert(tdbb, counter->lock, LCK_PW, LCK_WAIT);
			result = LCK_read_data(tdbb, counter->lock);

			// zero IDs are somewhat special, so let's better skip them
			if (!result)
				result = 1;

			counter->curVal = result;
			counter->maxVal = result + prefetch - 1;
			LCK_write_data(tdbb, counter->lock, counter->maxVal + 1);
			LCK_convert(tdbb, counter->lock, LCK_SR, LCK_WAIT);
		}

		return result;
	}
Example #2
0
	SLONG Database::SharedCounter::generate(thread_db* tdbb, ULONG space, ULONG prefetch)
	{
		fb_assert(space < TOTAL_ITEMS);
		ValueCache* const counter = &m_counters[space];
		Database* const dbb = tdbb->getDatabase();

		if (!counter->lock)
		{
			Lock* const lock = FB_NEW_RPT(*dbb->dbb_permanent, sizeof(SLONG)) Lock();
			counter->lock = lock;
			lock->lck_type = LCK_shared_counter;
			lock->lck_owner_handle = LCK_get_owner_handle(tdbb, lock->lck_type);
			lock->lck_parent = dbb->dbb_lock;
			lock->lck_length = sizeof(SLONG);
			lock->lck_key.lck_long = space;
			lock->lck_dbb = dbb;
			lock->lck_ast = blockingAst;
			lock->lck_object = counter;
			LCK_lock(tdbb, lock, LCK_PW, LCK_WAIT);

			counter->curVal = 1;
			counter->maxVal = 0;
		}

		if (counter->curVal > counter->maxVal)
		{
			LCK_convert(tdbb, counter->lock, LCK_PW, LCK_WAIT);

			counter->curVal = LCK_read_data(tdbb, counter->lock);

			if (!counter->curVal)
			{
				// zero IDs are somewhat special, so let's better skip them
				counter->curVal = 1;
			}

			counter->maxVal = counter->curVal + prefetch - 1;
			LCK_write_data(tdbb, counter->lock, counter->maxVal + 1);
		}

		return counter->curVal++;
	}