@@ -93,7 +93,6 @@ void init_socket_name(const char* the_socket_name) {
93
93
94
94
static void external_process_check ()
95
95
{
96
- DBGVAR (cerr,&(socket_name_file));
97
96
if (remote_client) return ;
98
97
if (::access (socket_name_file, F_OK) != 0 ) {
99
98
::sleep (1 ); // give me a chance to die with my parent process
@@ -106,7 +105,30 @@ static void external_process_check()
106
105
}
107
106
}
108
107
108
+ static int first_ppid=-1 ;
109
109
110
+ void check_parent_pid (){
111
+ int new_ppid=::getppid ();
112
+ if (first_ppid==-1 ){ // Initialize first_ppid
113
+ first_ppid=new_ppid;
114
+ }
115
+ // Check if ppid has changed, if client is in own namespace,
116
+ // the ppid will be forever 0 and never change.
117
+ // If the client runs as udfplugin the ppid will point to the exasql process
118
+ // and will change if it gets killed. Then client gets an orphaned process and
119
+ // will be adopted by another process
120
+ if (first_ppid!=new_ppid){
121
+ ::sleep (1 ); // give me a chance to die with my parent process
122
+ cerr << " exaudfclient aborting " << socket_name_str << " ... current pid_sum " << new_ppid << " different to first_pid_sum " << first_ppid << " ." << endl;
123
+ #ifdef SWIGVM_LOG_CLIENT
124
+ cerr << " ### SWIGVM aborting with name '" << socket_name_str
125
+ << " ' (" << ::getppid () << ' ,' << ::getpid () << ' )' << endl;
126
+ #endif
127
+ ::unlink (socket_name_file);
128
+ ::abort ();
129
+ }
130
+
131
+ }
110
132
111
133
void set_remote_client (bool value) {
112
134
remote_client = value;
@@ -123,6 +145,7 @@ void *check_thread_routine(void* data)
123
145
{
124
146
while (keep_checking) {
125
147
external_process_check ();
148
+ check_parent_pid ();
126
149
::usleep (100000 );
127
150
}
128
151
return NULL ;
@@ -142,10 +165,36 @@ void cancel_check_thread() {
142
165
::pthread_cancel (check_thread);
143
166
}
144
167
168
+ void print_args (int argc,char **argv){
169
+ for (int i = 0 ; i<argc; i++)
170
+ {
171
+ cerr << " zmqcontainerclient argv[" << i << " ] = " << argv[i] << endl;
172
+ }
173
+ }
174
+
175
+
176
+ void delete_vm (SWIGVM*& vm){
177
+ if (vm != nullptr )
178
+ {
179
+ delete vm;
180
+ vm = nullptr ;
181
+ }
182
+ }
183
+
184
+ void stop_all (zmq::socket_t & socket){
185
+ socket.close ();
186
+ stop_check_thread ();
187
+ if (!get_remote_client ()) {
188
+ cancel_check_thread ();
189
+ ::unlink (socket_name_file);
190
+ } else {
191
+ ::sleep (3 ); // give other components time to shutdown
192
+ }
193
+ }
194
+
145
195
mutex zmq_socket_mutex;
146
196
static bool use_zmq_socket_locks = false ;
147
197
148
-
149
198
void socket_send (zmq::socket_t &socket, zmq::message_t &zmsg)
150
199
{
151
200
DBG_FUNC_BEGIN (std::cerr);
@@ -1451,6 +1500,7 @@ class SWIGResultHandler_Impl : public SWIGRAbstractResultHandler, SWIGGeneralIte
1451
1500
1452
1501
} // namespace SWIGVMContainers
1453
1502
1503
+
1454
1504
extern " C" {
1455
1505
1456
1506
SWIGVMContainers::SWIGMetadata* create_SWIGMetaData () {
@@ -1465,8 +1515,6 @@ SWIGVMContainers::SWIGRAbstractResultHandler* create_SWIGResultHandler(SWIGVMCon
1465
1515
return new SWIGVMContainers::SWIGResultHandler_Impl (table_iterator);
1466
1516
}
1467
1517
1468
-
1469
-
1470
1518
int exaudfclient_main (std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1471
1519
{
1472
1520
assert (SWIGVM_params_ref != nullptr );
@@ -1485,12 +1533,7 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1485
1533
1486
1534
zmq::context_t context (1 );
1487
1535
1488
- #ifdef SWIGVM_LOG_CLIENT
1489
- for (int i = 0 ; i<argc; i++)
1490
- {
1491
- cerr << " zmqcontainerclient argv[" << i << " ] = " << argv[i] << endl;
1492
- }
1493
- #endif
1536
+ DBG_COND_FUNC_CALL (cerr, print_args (argc,argv));
1494
1537
1495
1538
if (socket_name.length () > 4 ) {
1496
1539
#ifdef PROTEGRITY_PLUGIN_CLIENT
@@ -1531,12 +1574,7 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1531
1574
socket_name_file = &(socket_name_file[6 ]);
1532
1575
}
1533
1576
1534
- #ifdef SWIGVM_LOG_CLIENT
1535
- cerr << " ### SWIGVM starting " << argv[0 ] << " with name '" << socket_name
1536
- << " (" << ::getppid () << ' ,' << ::getpid () << " ): '"
1537
- << argv[1 ]
1538
- << ' \' ' << endl;
1539
- #endif
1577
+ DBG_STREAM_MSG (cerr," ### SWIGVM starting " << argv[0 ] << " with name '" << socket_name << " (" << ::getppid () << ' ,' << ::getpid () << " ): '" << argv[1 ] << ' \' ' );
1540
1578
1541
1579
start_check_thread ();
1542
1580
@@ -1551,6 +1589,7 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1551
1589
}
1552
1590
1553
1591
reinit:
1592
+
1554
1593
DBGMSG (cerr," Reinit" );
1555
1594
zmq::socket_t socket (context, ZMQ_REQ);
1556
1595
@@ -1564,12 +1603,15 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1564
1603
SWIGVM_params_ref->sock = &socket;
1565
1604
SWIGVM_params_ref->exch = &exchandler;
1566
1605
1606
+ SWIGVM*vm=nullptr ;
1607
+
1567
1608
if (!send_init (socket, socket_name)) {
1568
1609
if (!get_remote_client () && exchandler.exthrowed ) {
1569
1610
send_close (socket, exchandler.exmsg );
1570
- return 1 ;
1611
+ goto error;
1612
+ }else {
1613
+ goto reinit;
1571
1614
}
1572
- goto reinit;
1573
1615
}
1574
1616
1575
1617
SWIGVM_params_ref->dbname = (char *) g_database_name.c_str ();
@@ -1587,13 +1629,11 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1587
1629
SWIGVM_params_ref->vm_id = g_vm_id;
1588
1630
SWIGVM_params_ref->singleCallMode = g_singleCallMode;
1589
1631
1590
- SWIGVM*vm=nullptr ;
1591
-
1592
1632
try {
1593
1633
vm = vmMaker ();
1594
1634
if (vm == nullptr ) {
1595
1635
send_close (socket, " Unknown or unsupported VM type" );
1596
- return 1 ;
1636
+ goto error ;
1597
1637
}
1598
1638
if (vm->exception_msg .size ()>0 ) {
1599
1639
throw SWIGVM::exception (vm->exception_msg .c_str ());
@@ -1608,49 +1648,49 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1608
1648
// EXASolution responds with a CALL message that specifies
1609
1649
// the single call function to be made
1610
1650
if (!send_run (socket)) {
1611
- break ;
1612
- }
1651
+ break ;
1652
+ }
1653
+
1613
1654
assert (g_singleCallFunction != single_call_function_id_e::SC_FN_NIL);
1614
- try {
1615
- const char * result = nullptr ;
1655
+ try {
1656
+ const char * result = nullptr ;
1616
1657
switch (g_singleCallFunction)
1617
1658
{
1618
- case single_call_function_id_e::SC_FN_NIL:
1619
- break ;
1620
- case single_call_function_id_e::SC_FN_DEFAULT_OUTPUT_COLUMNS:
1621
- result = vm->singleCall (g_singleCallFunction,noArg);
1622
- break ;
1623
- case single_call_function_id_e::SC_FN_GENERATE_SQL_FOR_IMPORT_SPEC:
1624
- assert (!g_singleCall_ImportSpecificationArg.isEmpty ());
1625
- result = vm->singleCall (g_singleCallFunction,g_singleCall_ImportSpecificationArg);
1626
- g_singleCall_ImportSpecificationArg = ExecutionGraph::ImportSpecification (); // delete the last argument
1627
- break ;
1628
- case single_call_function_id_e::SC_FN_GENERATE_SQL_FOR_EXPORT_SPEC:
1629
- assert (!g_singleCall_ExportSpecificationArg.isEmpty ());
1630
- result = vm->singleCall (g_singleCallFunction,g_singleCall_ExportSpecificationArg);
1631
- g_singleCall_ExportSpecificationArg = ExecutionGraph::ExportSpecification (); // delete the last argument
1632
- break ;
1633
- case single_call_function_id_e::SC_FN_VIRTUAL_SCHEMA_ADAPTER_CALL:
1634
- assert (!g_singleCall_StringArg.isEmpty ());
1635
- result = vm->singleCall (g_singleCallFunction,g_singleCall_StringArg);
1636
- break ;
1659
+ case single_call_function_id_e::SC_FN_NIL:
1660
+ break ;
1661
+ case single_call_function_id_e::SC_FN_DEFAULT_OUTPUT_COLUMNS:
1662
+ result = vm->singleCall (g_singleCallFunction,noArg);
1663
+ break ;
1664
+ case single_call_function_id_e::SC_FN_GENERATE_SQL_FOR_IMPORT_SPEC:
1665
+ assert (!g_singleCall_ImportSpecificationArg.isEmpty ());
1666
+ result = vm->singleCall (g_singleCallFunction,g_singleCall_ImportSpecificationArg);
1667
+ g_singleCall_ImportSpecificationArg = ExecutionGraph::ImportSpecification (); // delete the last argument
1668
+ break ;
1669
+ case single_call_function_id_e::SC_FN_GENERATE_SQL_FOR_EXPORT_SPEC:
1670
+ assert (!g_singleCall_ExportSpecificationArg.isEmpty ());
1671
+ result = vm->singleCall (g_singleCallFunction,g_singleCall_ExportSpecificationArg);
1672
+ g_singleCall_ExportSpecificationArg = ExecutionGraph::ExportSpecification (); // delete the last argument
1673
+ break ;
1674
+ case single_call_function_id_e::SC_FN_VIRTUAL_SCHEMA_ADAPTER_CALL:
1675
+ assert (!g_singleCall_StringArg.isEmpty ());
1676
+ result = vm->singleCall (g_singleCallFunction,g_singleCall_StringArg);
1677
+ break ;
1637
1678
}
1638
1679
if (vm->exception_msg .size ()>0 ) {
1639
- send_close (socket, vm->exception_msg ); socket. close ();
1680
+ send_close (socket, vm->exception_msg );
1640
1681
goto error;
1641
1682
}
1642
1683
1643
1684
if (vm->calledUndefinedSingleCall .size ()>0 ) {
1644
- send_undefined_call (socket, vm->calledUndefinedSingleCall );
1645
- } else {
1646
- send_return (socket,result);
1647
- }
1685
+ send_undefined_call (socket, vm->calledUndefinedSingleCall );
1686
+ } else {
1687
+ send_return (socket,result);
1688
+ }
1648
1689
1649
1690
if (!send_done (socket)) {
1650
1691
break ;
1651
1692
}
1652
- } catch (...) {
1653
- }
1693
+ } catch (...) {}
1654
1694
}
1655
1695
} else {
1656
1696
for (;;) {
@@ -1660,7 +1700,7 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1660
1700
while (!vm->run_ ())
1661
1701
{
1662
1702
if (vm->exception_msg .size ()>0 ) {
1663
- send_close (socket, vm->exception_msg ); socket. close ();
1703
+ send_close (socket, vm->exception_msg );
1664
1704
goto error;
1665
1705
}
1666
1706
}
@@ -1673,66 +1713,35 @@ int exaudfclient_main(std::function<SWIGVM*()>vmMaker,int argc,char**argv)
1673
1713
{
1674
1714
vm->shutdown ();
1675
1715
if (vm->exception_msg .size ()>0 ) {
1676
- send_close (socket, vm->exception_msg ); socket. close ();
1716
+ send_close (socket, vm->exception_msg );
1677
1717
goto error;
1678
1718
}
1679
- delete vm;
1680
- vm = NULL ;
1681
1719
}
1682
1720
send_finished (socket);
1683
1721
} catch (SWIGVM::exception &err) {
1684
- keep_checking = false ;
1685
- send_close (socket, err.what ()); socket.close ();
1686
-
1687
- #ifdef SWIGVM_LOG_CLIENT
1688
- cerr << " ### SWIGVM crashing with name '" << socket_name
1689
- << " (" << ::getppid () << ' ,' << ::getpid () << " ): " << err.what () << endl;
1690
- #endif
1722
+ DBG_STREAM_MSG (cerr," ### SWIGVM crashing with name '" << socket_name << " (" << ::getppid () << ' ,' << ::getpid () << " ): " << err.what ());
1723
+ send_close (socket, err.what ());
1691
1724
goto error;
1692
1725
} catch (std::exception &err) {
1693
- send_close (socket, err.what ()); socket.close ();
1694
- #ifdef SWIGVM_LOG_CLIENT
1695
- cerr << " ### SWIGVM crashing with name '" << socket_name
1696
- << " (" << ::getppid () << ' ,' << ::getpid () << " ): " << err.what () << endl;
1697
- #endif
1726
+ DBG_STREAM_MSG (cerr," ### SWIGVM crashing with name '" << socket_name << " (" << ::getppid () << ' ,' << ::getpid () << " ): " << err.what ());
1727
+ send_close (socket, err.what ());
1698
1728
goto error;
1699
1729
} catch (...) {
1700
- send_close (socket, " Internal/Unknown error" ); socket.close ();
1701
- #ifdef SWIGVM_LOG_CLIENT
1702
- cerr << " ### SWIGVM crashing with name '" << socket_name
1703
- << " (" << ::getppid () << ' ,' << ::getpid () << ' )' << endl;
1704
- #endif
1730
+ DBG_STREAM_MSG (cerr," ### SWIGVM crashing with name '" << socket_name << " (" << ::getppid () << ' ,' << ::getpid () << ' )' );
1731
+ send_close (socket, " Internal/Unknown error" );
1705
1732
goto error;
1706
1733
}
1707
1734
1708
- #ifdef SWIGVM_LOG_CLIENT
1709
- cerr << " ### SWIGVM finishing with name '" << socket_name
1710
- << " (" << ::getppid () << ' ,' << ::getpid () << ' )' << endl;
1711
- #endif
1712
- stop_check_thread ();
1713
- socket.close ();
1714
- if (!get_remote_client ()) {
1715
- cancel_check_thread ();
1716
- ::unlink (socket_name_file);
1717
- }
1735
+
1736
+ DBG_STREAM_MSG (cerr," ### SWIGVM finishing with name '" << socket_name << " (" << ::getppid () << ' ,' << ::getpid () << ' )' );
1737
+
1738
+ delete_vm (vm);
1739
+ stop_all (socket);
1718
1740
return 0 ;
1719
1741
1720
1742
error:
1721
- keep_checking = false ;
1722
- if (vm != NULL )
1723
- {
1724
- vm->shutdown ();
1725
- delete vm;
1726
- vm = NULL ;
1727
- }
1728
-
1729
- socket.close ();
1730
- if (!get_remote_client ()) {
1731
- cancel_check_thread ();
1732
- ::unlink (socket_name_file);
1733
- } else {
1734
- ::sleep (3 ); // give other components time to shutdown
1735
- }
1743
+ delete_vm (vm);
1744
+ stop_all (socket);
1736
1745
return 1 ;
1737
1746
}
1738
1747
0 commit comments