Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Prevent delegates used for native callbacks from being disposed while in use. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessionStreamManager |
Files: | files | file ages | folders |
SHA1: |
489188361e5126829141bd14b23f1e13 |
User & Date: | mistachkin 2017-10-13 17:11:54.527 |
Context
2017-10-13
| ||
17:46 | Corrections to tests. Closed-Leaf check-in: acbeea6018 user: mistachkin tags: sessionStreamManager | |
17:11 | Prevent delegates used for native callbacks from being disposed while in use. check-in: 489188361e user: mistachkin tags: sessionStreamManager | |
16:47 | Further adjustments. check-in: fc3f62b4be user: mistachkin tags: sessionStreamManager | |
Changes
Changes to System.Data.SQLite/SQLiteSession.cs.
︙ | ︙ | |||
11 12 13 14 15 16 17 | #if DEBUG using System.Diagnostics; #endif using System.IO; using System.Globalization; using System.Runtime.InteropServices; | < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #if DEBUG using System.Diagnostics; #endif using System.IO; using System.Globalization; using System.Runtime.InteropServices; namespace System.Data.SQLite { #region Session Extension Enumerations public enum SQLiteChangeSetConflictType { Data = 1, |
︙ | ︙ | |||
744 745 746 747 748 749 750 | IntPtr iterator = IntPtr.Zero; try { streamAdapter = new SQLiteStreamAdapter(stream, flags); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_start_strm( | | | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 | IntPtr iterator = IntPtr.Zero; try { streamAdapter = new SQLiteStreamAdapter(stream, flags); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_start_strm( ref iterator, streamAdapter.GetInputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) { throw new SQLiteException( rc, "sqlite3changeset_start_strm"); } |
︙ | ︙ | |||
836 837 838 839 840 841 842 843 844 845 846 847 848 849 | #region SQLiteStreamAdapter Class internal sealed class SQLiteStreamAdapter : IDisposable { #region Private Data private Stream stream; /* EXEMPT: NOT OWNED */ private SQLiteConnectionFlags flags; #endregion /////////////////////////////////////////////////////////////////////// #region Public Constructors public SQLiteStreamAdapter( Stream stream, | > > > > > | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 | #region SQLiteStreamAdapter Class internal sealed class SQLiteStreamAdapter : IDisposable { #region Private Data private Stream stream; /* EXEMPT: NOT OWNED */ private SQLiteConnectionFlags flags; /////////////////////////////////////////////////////////////////////// private UnsafeNativeMethods.xSessionInput xInput; private UnsafeNativeMethods.xSessionOutput xOutput; #endregion /////////////////////////////////////////////////////////////////////// #region Public Constructors public SQLiteStreamAdapter( Stream stream, |
︙ | ︙ | |||
862 863 864 865 866 867 868 869 | { return flags; } #endregion /////////////////////////////////////////////////////////////////////// #region Native Callback Methods | > > > > > > > > > > > > > > > > > > > > > > > > > > | < < | < | 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 | { return flags; } #endregion /////////////////////////////////////////////////////////////////////// #region Public Methods public UnsafeNativeMethods.xSessionInput GetInputDelegate() { CheckDisposed(); if (xInput == null) xInput = new UnsafeNativeMethods.xSessionInput(Input); return xInput; } /////////////////////////////////////////////////////////////////////// public UnsafeNativeMethods.xSessionOutput GetOutputDelegate() { CheckDisposed(); if (xOutput == null) xOutput = new UnsafeNativeMethods.xSessionOutput(Output); return xOutput; } #endregion /////////////////////////////////////////////////////////////////////// #region Native Callback Methods private SQLiteErrorCode Input( IntPtr context, IntPtr pData, ref int nData ) { try { Stream localStream = stream; if (localStream == null) return SQLiteErrorCode.Misuse; if (nData > 0) { byte[] bytes = new byte[nData]; |
︙ | ︙ | |||
903 904 905 906 907 908 909 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, | | | < < | < | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, "xSessionInput", e)); /* throw */ } } catch { // do nothing. } } return SQLiteErrorCode.IoErr_Read; } /////////////////////////////////////////////////////////////////////// private SQLiteErrorCode Output( IntPtr context, IntPtr pData, int nData ) { try { Stream localStream = stream; if (localStream == null) return SQLiteErrorCode.Misuse; if (nData > 0) { byte[] bytes = new byte[nData]; |
︙ | ︙ | |||
958 959 960 961 962 963 964 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, | | | 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, "xSessionOutput", e)); /* throw */ } } catch { // do nothing. } } |
︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 | if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// | > > > > > > > > > < < | 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 | if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// if (xInput != null) xInput = null; if (xOutput != null) xOutput = null; if (stream != null) stream = null; /* NOT OWNED */ } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { // // NOTE: Everything should be fully disposed at this point. // |
︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for input stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changegroup_add_strm( | | | 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for input stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changegroup_add_strm( changeGroup, streamAdapter.GetInputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changegroup_add_strm"); } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
1379 1380 1381 1382 1383 1384 1385 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for output stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changegroup_output_strm( | | | 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for output stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changegroup_output_strm( changeGroup, streamAdapter.GetOutputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changegroup_output_strm"); } #endregion /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | /////////////////////////////////////////////////////////////////////// private IntPtr session; /////////////////////////////////////////////////////////////////////// private SessionTableFilterCallback tableFilterCallback; private object tableFilterClientData; #endregion /////////////////////////////////////////////////////////////////////// #region Public Constructors | > | 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | /////////////////////////////////////////////////////////////////////// private IntPtr session; /////////////////////////////////////////////////////////////////////// private UnsafeNativeMethods.xSessionFilter xFilter; private SessionTableFilterCallback tableFilterCallback; private object tableFilterClientData; #endregion /////////////////////////////////////////////////////////////////////// #region Public Constructors |
︙ | ︙ | |||
1532 1533 1534 1535 1536 1537 1538 | /////////////////////////////////////////////////////////////////////// private UnsafeNativeMethods.xSessionFilter ApplyTableFilter( SessionTableFilterCallback callback, /* in: NULL OK */ object clientData /* in: NULL OK */ ) { | | | > > > > > | > > > | > > | 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | /////////////////////////////////////////////////////////////////////// private UnsafeNativeMethods.xSessionFilter ApplyTableFilter( SessionTableFilterCallback callback, /* in: NULL OK */ object clientData /* in: NULL OK */ ) { tableFilterCallback = callback; tableFilterClientData = clientData; if (callback == null) { if (xFilter != null) xFilter = null; return null; } if (xFilter == null) xFilter = new UnsafeNativeMethods.xSessionFilter(Filter); return xFilter; } /////////////////////////////////////////////////////////////////////// private void InitializeStreamManager() { if (streamManager != null) |
︙ | ︙ | |||
1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 | Stream stream ) { InitializeStreamManager(); return streamManager.GetAdapter(stream); } /////////////////////////////////////////////////////////////////////// #region Native Callback Methods | > | | < | 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 | Stream stream ) { InitializeStreamManager(); return streamManager.GetAdapter(stream); } #endregion /////////////////////////////////////////////////////////////////////// #region Native Callback Methods private int Filter( IntPtr context, /* NOT USED */ IntPtr pTblName ) { try { return tableFilterCallback(tableFilterClientData, SQLiteString.StringFromUtf8IntPtr(pTblName)) ? 1 : 0; } catch (Exception e) { try { if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( /* throw */ SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, "xSessionFilter", e)); } } catch { // do nothing. } } return 0; } #endregion /////////////////////////////////////////////////////////////////////// #region ISQLiteSession Members public bool IsEnabled() { |
︙ | ︙ | |||
1753 1754 1755 1756 1757 1758 1759 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for output stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3session_changeset_strm( | | | 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for output stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3session_changeset_strm( session, streamAdapter.GetOutputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3session_changeset_strm"); } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for output stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3session_patchset_strm( | | | 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 | if (streamAdapter == null) { throw new SQLiteException( "could not get or create adapter for output stream"); } SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3session_patchset_strm( session, streamAdapter.GetOutputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3session_patchset_strm"); } /////////////////////////////////////////////////////////////////////// |
︙ | ︙ | |||
1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 | if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// if (streamManager != null) { streamManager.Dispose(); streamManager = null; } } | > > > | 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 | if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// if (xFilter != null) xFilter = null; if (streamManager != null) { streamManager.Dispose(); streamManager = null; } } |
︙ | ︙ | |||
1996 1997 1998 1999 2000 2001 2002 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( /* throw */ SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, | | | 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( /* throw */ SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, "xSessionFilter", e)); } } catch { // do nothing. } } |
︙ | ︙ | |||
2052 2053 2054 2055 2056 2057 2058 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( /* throw */ SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, | | | 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 | if (HelperMethods.LogCallbackExceptions(GetFlags())) { SQLiteLog.LogMessage( /* throw */ SQLiteBase.COR_E_EXCEPTION, HelperMethods.StringFormat( CultureInfo.CurrentCulture, UnsafeNativeMethods.ExceptionMessageFormat, "xSessionConflict", e)); } } catch { // do nothing. } } |
︙ | ︙ | |||
2467 2468 2469 2470 2471 2472 2473 | public ISQLiteChangeSet Invert() { CheckDisposed(); CheckInputStream(); CheckOutputStream(); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_invert_strm( | | | | 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 | public ISQLiteChangeSet Invert() { CheckDisposed(); CheckInputStream(); CheckOutputStream(); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_invert_strm( inputStreamAdapter.GetInputDelegate(), IntPtr.Zero, outputStreamAdapter.GetOutputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changeset_invert_strm"); return null; } |
︙ | ︙ | |||
2498 2499 2500 2501 2502 2503 2504 | throw new ArgumentException( "not a stream based change set", "changeSet"); } streamChangeSet.CheckInputStream(); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_concat_strm( | | | > | | 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 | throw new ArgumentException( "not a stream based change set", "changeSet"); } streamChangeSet.CheckInputStream(); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_concat_strm( inputStreamAdapter.GetInputDelegate(), IntPtr.Zero, streamChangeSet.inputStreamAdapter.GetInputDelegate(), IntPtr.Zero, outputStreamAdapter.GetOutputDelegate(), IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changeset_concat_strm"); return null; } |
︙ | ︙ | |||
2541 2542 2543 2544 2545 2546 2547 | UnsafeNativeMethods.xSessionFilter xFilter = GetDelegate( tableFilterCallback, clientData); UnsafeNativeMethods.xSessionConflict xConflict = GetDelegate( conflictCallback, clientData); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_apply_strm( | | | | 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 | UnsafeNativeMethods.xSessionFilter xFilter = GetDelegate( tableFilterCallback, clientData); UnsafeNativeMethods.xSessionConflict xConflict = GetDelegate( conflictCallback, clientData); SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3changeset_apply_strm( GetIntPtr(), inputStreamAdapter.GetInputDelegate(), IntPtr.Zero, xFilter, xConflict, IntPtr.Zero); if (rc != SQLiteErrorCode.Ok) throw new SQLiteException(rc, "sqlite3changeset_apply_strm"); } #endregion /////////////////////////////////////////////////////////////////////// |
︙ | ︙ |
Changes to Tests/session.eagle.
︙ | ︙ | |||
470 471 472 473 474 475 476 | set session [$connection -alias CreateSession main] $session AttachTable null makeSomeChanges $db t1 [list insert update delete] set rawData [createMemoryChangeSetForSession $session] | < < | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | set session [$connection -alias CreateSession main] $session AttachTable null makeSomeChanges $db t1 [list insert update delete] set rawData [createMemoryChangeSetForSession $session] writeRawDataToFile $fileName(1) $rawData writeStreamChangeSetForSession $session $fileName(2) openStreamChangeSetForConnection $connection $fileName(2) "" state list [expr {[file size $fileName(1)] > 0}] \ [string equal [readFile $fileName(1)] [readFile $fileName(2)]] \ [changeSetToString $state(changeSet) true] |
︙ | ︙ |