diff --git a/xflaim/csharp/xflaim/Db.cpp b/xflaim/csharp/xflaim/Db.cpp
index 9754eb6..856e619 100644
--- a/xflaim/csharp/xflaim/Db.cpp
+++ b/xflaim/csharp/xflaim/Db.cpp
@@ -1410,3 +1410,81 @@ Exit:
return( rc);
}
+
+typedef FLMBOOL (FLMAPI * LOCK_INFO_CLIENT)(
+ FLMBOOL bSetTotalLocks,
+ FLMUINT32 ui32TotalLocks,
+ FLMUINT32 ui32LockNum,
+ FLMUINT32 ui32ThreadId,
+ FLMUINT32 ui32Time);
+
+/****************************************************************************
+Desc:
+****************************************************************************/
+class CS_LockInfoClient : public IF_LockInfoClient
+{
+public:
+
+ CS_LockInfoClient(
+ LOCK_INFO_CLIENT fnLockInfoClient)
+ {
+ m_fnLockInfoClient = fnLockInfoClient;
+ }
+
+ virtual ~CS_LockInfoClient()
+ {
+ }
+
+ FLMBOOL FLMAPI setLockCount(
+ FLMUINT uiTotalLocks)
+ {
+ return( m_fnLockInfoClient( TRUE, (FLMUINT32)uiTotalLocks, 0, 0, 0));
+ }
+
+ FLMBOOL FLMAPI addLockInfo(
+ FLMUINT uiLockNum,
+ FLMUINT uiThreadId,
+ FLMUINT uiTime)
+ {
+ return( m_fnLockInfoClient( FALSE, 0, (FLMUINT32)uiLockNum, (FLMUINT32)uiThreadId,
+ (FLMUINT32)uiTime));
+ }
+
+private:
+
+ LOCK_INFO_CLIENT m_fnLockInfoClient;
+};
+
+/****************************************************************************
+Desc:
+****************************************************************************/
+FLMEXTC FLMEXP RCODE FLMAPI xflaim_Db_getLockUsers(
+ IF_Db * pDb,
+ LOCK_INFO_CLIENT fnLockInfoClient)
+{
+ RCODE rc = NE_XFLM_OK;
+ IF_LockInfoClient * pLockInfoClient = NULL;
+
+ if (fnLockInfoClient)
+ {
+ if ((pLockInfoClient = f_new CS_LockInfoClient( fnLockInfoClient)) == NULL)
+ {
+ rc = RC_SET( NE_XFLM_MEM);
+ goto Exit;
+ }
+ }
+
+ if (RC_BAD( rc = pDb->getLockWaiters( pLockInfoClient)))
+ {
+ goto Exit;
+ }
+
+Exit:
+
+ if (pLockInfoClient)
+ {
+ pLockInfoClient->Release();
+ }
+
+ return( rc);
+}
diff --git a/xflaim/csharp/xflaim/Db.cs b/xflaim/csharp/xflaim/Db.cs
index 03e3e9f..645ebc7 100644
--- a/xflaim/csharp/xflaim/Db.cs
+++ b/xflaim/csharp/xflaim/Db.cs
@@ -745,6 +745,24 @@ namespace xflaim
FLM_LOCK_SHARED
}
+ ///
+ /// This object contains information about a lock holder or lock waiter.
+ ///
+ public class LockUser
+ {
+ ///
+ /// Thread ID that is either holding the lock or waiting for it.
+ ///
+ public uint uiThreadId;
+ ///
+ /// If this represents the lock holder, this is the amount of time
+ /// that the thread has been holding the lock. If it represents
+ /// the lock waiter, it is the amount of time the thread has been
+ /// waiting to obtain the lock. Time is in milliseconds.
+ ///
+ public uint uiTime;
+ }
+
///
/// Types of locks that may be requested.
/// IMPORTANT NOTE: These need to be kept in sync with the corresponding
@@ -3933,124 +3951,78 @@ namespace xflaim
out IntPtr ppszStr);
//-----------------------------------------------------------------------------
-// getLockWaiters
+// getLockUsers
//-----------------------------------------------------------------------------
-#if TODO
- /**
- * Get the list of threads that are holding the database lock as well as
- * the threads that are waiting to obtain the database lock.
- * @return Returns an array of {@link xflaim.LockUser LockUser} objects. The
- * zeroeth element in the array is the current holder of the database lock.
- * All other elements of the array are threads that are waiting to obtain
- * the lock.
- * @throws XFlaimException
- */
- public LockUser[] getLockWaiters() throws XFlaimException
- {
- return( _getLockWaiters( m_this));
- }
-#endif
-
-//-----------------------------------------------------------------------------
-// setDeleteStatusObject
-//-----------------------------------------------------------------------------
-
-#if TODO
- /**
- * Set a callback object that will report the progress of an index or
- * collection deletion operation. This object's methods are called only if
- * the index or collection is deleted in the foreground. The delete operation
- * must be performed in the same thread where this method is called.
- * @param deleteStatusObj An object that implements the {@link xflaim.DeleteStatus
- * DeleteStatus} interface.
- * @throws XFlaimException
- */
- public void setDeleteStatusObject(
- DeleteStatus deleteStatusObj) throws XFlaimException
- {
- _setDeleteStatusObject( m_this, deleteStatusObj);
- }
-#endif
-
-//-----------------------------------------------------------------------------
-// setIndexingClientObject
-//-----------------------------------------------------------------------------
-
-#if TODO
- /**
- * Set a callback object that will report each document that is being indexed when
- * an index definition object is added. This object's methods are called only if
- * the index is added in the foreground. The index definition must be added
- * in the same thread that sets this object.
- * @param ixClientObj An object that implements the {@link xflaim.IxClient
- * IxClient} interface.
- * @throws XFlaimException
- */
- public void setIndexingClientObject(
- IxClient ixClientObj) throws XFlaimException
- {
- _setIndexingClientObject( m_this, ixClientObj);
- }
-#endif
-
-//-----------------------------------------------------------------------------
-// setIndexingStatusObject
-//-----------------------------------------------------------------------------
-
-#if TODO
- /**
- * Set a callback object that will report indexing progress when
- * an index definition object is added. This object's methods are called only if
- * the index is added in the foreground. The index definition must be added
- * in the same thread that sets this object.
- * @param ixStatusObj An object that implements the {@link xflaim.IxStatus
- * IxStatus} interface.
- * @throws XFlaimException
- */
- public void setIndexingStatusObject(
- IxStatus ixStatusObj) throws XFlaimException
- {
- _setIndexingStatusObject( m_this, ixStatusObj);
- }
-#endif
-
-//-----------------------------------------------------------------------------
-// setCommitClientObject
-//-----------------------------------------------------------------------------
-
-#if TODO
- /**
- * Set a callback object that will be called after a transaction commit
- * has safely saved all transaction data to disk, but before the database
- * is unlocked. This allows an application to do anything it may need to do
- * after a commit but before the database is unlocked. The thread that
- * performs the commit must be the thread that sets this object.
- * @param commitClientObj An object that implements the {@link xflaim.CommitClient
- * CommitClient} interface.
- * @throws XFlaimException
- */
- public void setCommitClientObject(
- CommitClient commitClientObj) throws XFlaimException
- {
- _setCommitClientObject( m_this, commitClientObj);
- }
-#endif
-
-//-----------------------------------------------------------------------------
-// upgrade
-//-----------------------------------------------------------------------------
-
-#if TODO
- /**
- * Upgrade the database to the most current database version.
- * @throws XFlaimException
- */
- public void upgrade() throws XFlaimException
- {
- _upgrade( m_this);
- }
-#endif
-
+ ///
+ /// Returns an array representing all of the threads that are either
+ /// holding the database lock (this is always the zeroeth entry in the array)
+ /// as well as threads waiting to obtain the database lock (entries
+ /// 1 through N).
+ ///
+ /// Array of database lock holder and waiters.
+ public LockUser [] getLockUsers()
+ {
+ RCODE rc;
+ LockInfoClientDelegate lockInfoClientDelegate = new LockInfoClientDelegate();
+ LockInfoClientCallback fnLockInfoClient = new LockInfoClientCallback( lockInfoClientDelegate.funcLockInfoClient);
+
+ if ((rc = xflaim_Db_getLockUsers( m_pDb, fnLockInfoClient)) != 0)
+ {
+ throw new XFlaimException( rc);
+ }
+ return( lockInfoClientDelegate.getLockUsers());
+ }
+
+ [DllImport("xflaim",CharSet=CharSet.Ansi)]
+ private static extern RCODE xflaim_Db_getLockUsers(
+ IntPtr pDb,
+ LockInfoClientCallback fnLockInfoClient);
+
+ private delegate int LockInfoClientCallback(
+ int bSetTotalLocks,
+ uint uiTotalLocks,
+ uint uiLockNum,
+ uint uiThreadId,
+ uint uiTime);
+
+ private class LockInfoClientDelegate
+ {
+ LockUser [] m_lockUsers;
+
+ public LockInfoClientDelegate()
+ {
+ m_lockUsers = null;
+ }
+
+ ~LockInfoClientDelegate()
+ {
+ }
+
+ public LockUser [] getLockUsers()
+ {
+ return( m_lockUsers);
+ }
+
+ public int funcLockInfoClient(
+ int bSetTotalLocks,
+ uint uiTotalLocks,
+ uint uiLockNum,
+ uint uiThreadId,
+ uint uiTime)
+ {
+ if (bSetTotalLocks != 0)
+ {
+ m_lockUsers = new LockUser [uiTotalLocks];
+ }
+ else
+ {
+ LockUser lockUser = m_lockUsers [uiLockNum] = new LockUser();
+ lockUser.uiThreadId = uiThreadId;
+ lockUser.uiTime = uiTime;
+ }
+ return( 1);
+ }
+ }
}
}