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); + } + } } }