SELECT of OCILobLocator in Non Blocking mode

Hi all.
I have problem:
I try select BLOB field into OCILobLocator* buffer in Non Blocking mode, and receive 'ORA-03106: fatal two-task communication protocol error' sometimes.
Details:
Application contains two threads : 1. select blob field, 2. update it.
I tried separate update and select to different apps (and run its in one time) - problem reproduced.
problem reproduced for OCIStmtFetch and OCIStmtFetch2.
If disable non blocking mode - problem disappear.
if error appear - record level error code contains 1405. Need wait few minutes for error message appearing (~1 minute in my case).
Using of OCI_DEFAULT in OCIDefineByPos instead OCI_DYNAMIC_FETCH don't solve problem.
I use oracle server and client library with version 10.2.0.4
Output sample:
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #877: 1405
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #54: 1405
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #877: 1405
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #54: 1405
Can anybody help me ?
m.b. exists workaround ?
#include <iostream>
#include <sstream>
#include <assert.h>
#include <oci.h>
#define _DYN 1
before run this test run next sql at DB:
CREATE TABLE ADSERVERTEST_BLOB(id NUMBER(10), text BLOB);
BEGIN
FOR i IN 0..999 LOOP
INSERT INTO ADSERVERTEST_BLOB(id, text) VALUES(i, utl_raw.cast_to_raw('init'));
END LOOP;
END;
template<typename Type, unsigned long TypeId>
class OCIHandlePtr
public:
OCIHandlePtr(): handle_(0) {}
OCIHandlePtr(Type* handle): handle_(handle) {}
~OCIHandlePtr()
reset(0);
void reset(Type* handle)
if(handle_)
sword result;
if((result = OCIHandleFree(
handle_,
TypeId)) != OCI_SUCCESS)
assert(0);
std::cerr << "Can't make OCIHandleFree" << std::endl;
handle_ = handle;
Type* get()
return handle_;
Type*& fill()
reset(0);
return handle_;
private:
Type* handle_;
template<typename Type, unsigned long TypeId>
class OCIDescriptorPtr
public:
OCIDescriptorPtr(): handle_(0) {}
OCIDescriptorPtr(Type* handle): handle_(handle) {}
~OCIDescriptorPtr()
reset(0);
void reset(Type* handle)
if(handle_)
sword result;
if((result = OCIDescriptorFree(
handle_,
TypeId)) != OCI_SUCCESS)
std::cerr << "Can't make OCIDescriptorFree" << std::endl;
handle_ = handle;
Type* get()
return handle_;
Type*& fill()
reset(0);
return handle_;
private:
Type* handle_;
void throw_oci_error(
const char* fun,
const char* oci_op,
long status,
OCIError* oci_error_handler,
const char* query = 0)
std::cerr << fun << ": can't make " << oci_op << ": status = " << status;
if(status == OCI_SUCCESS_WITH_INFO ||
status == OCI_ERROR)
std::cerr << ", message = '";
text err_buf[1024] = "";
sb4 err_code = 0;
OCIErrorGet(
oci_error_handler,
(ub4)1,
0,
&err_code,
err_buf,
sizeof(err_buf),
(ub4)OCI_HTYPE_ERROR);
std::cerr << err_buf << "', error code = " << err_code;
exit(1);
if(query)
std::cerr << ", sql = " << query;
OCIHandlePtr<OCIEnv, OCI_HTYPE_ENV> environment_handle;
void connect(
OCIEnv* environment_handle,
const char* db,
const char* user,
const char* password,
OCIHandlePtr<OCIError, OCI_HTYPE_ERROR>& error_handle,
OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER>& server_handle,
OCIHandlePtr<OCISession, OCI_HTYPE_SESSION>& session_handle,
OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX>& svc_context_handle)
static const char* FUN = "connect()";
sword result;
// allocate an error handle
if((result = OCIHandleAlloc(
environment_handle,
(void **) &error_handle.fill(),
OCI_HTYPE_ERROR,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// allocate a server handle
if((result = OCIHandleAlloc(
environment_handle,
(void **) &server_handle.fill(),
OCI_HTYPE_SERVER,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
if((result = OCIServerAttach(
server_handle.get(),
error_handle.get(),
(text*)db,
strlen(db),
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIServerAttach", result, error_handle.get());
// allocate a service handle
if((result = OCIHandleAlloc(
environment_handle,
(void **) &svc_context_handle.fill(),
OCI_HTYPE_SVCCTX,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// set the server attribute in the service context handle
if((result = OCIAttrSet(
svc_context_handle.get(),
OCI_HTYPE_SVCCTX,
server_handle.get(),
sizeof(OCIServer*),
OCI_ATTR_SERVER,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// allocate a user session handle
if((result = OCIHandleAlloc(
environment_handle,
(void **)&session_handle.fill(),
OCI_HTYPE_SESSION,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// set username and password attributes in user session handle
if((result = OCIAttrSet(
session_handle.get(),
OCI_HTYPE_SESSION,
(text*)user,
strlen(user),
OCI_ATTR_USERNAME,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
if((result = OCIAttrSet(
session_handle.get(),
OCI_HTYPE_SESSION,
(text*)password,
strlen(password),
OCI_ATTR_PASSWORD,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
// start the session
if((result = OCISessionBegin(
svc_context_handle.get(),
error_handle.get(),
session_handle.get(),
OCI_CRED_RDBMS,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCISessionBegin", result, error_handle.get());
// set the user session attribute in the service context handle
if((result = OCIAttrSet(
svc_context_handle.get(),
OCI_HTYPE_SVCCTX,
session_handle.get(),
sizeof(OCISession*),
OCI_ATTR_SESSION,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
ub1 attr_value = 1;
if((result = OCIAttrSet(
server_handle.get(),
OCI_HTYPE_SERVER,
&attr_value,
sizeof(attr_value),
OCI_ATTR_NONBLOCKING_MODE,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
void disconnect(
OCIEnv* environment_handle,
OCIError* error_handle,
OCIServer* server_handle,
OCISession* session_handle,
OCISvcCtx* svc_context_handle)
static const char* FUN = "disconnect()";
sword result;
if((result = OCISessionEnd(
svc_context_handle,
error_handle,
session_handle,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCISessionEnd", result, error_handle);
if((result = OCIServerDetach(
server_handle,
error_handle,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIServerDetach", result, error_handle);
OCILobLocator* FETCH_BUFFER_1[10000*1024];
char IND_BUFFER_1[10000*1024];
ub2 ERROR_BUFFER_1[1024];
OCIDefine* define_handle_1;
void clear_blob_buf(
OCILobLocator** buf,
unsigned long fetch_size)
for(unsigned long i = 0; i < 1024; ++i)
OCIDescriptorFree(
buf,
(ub4)OCI_DTYPE_LOB);
::memset(buf, 0, fetch_size * 1024);
uint32_t RET_LEN4;
sb4 oci_blob_callback(
dvoid* ctx,
OCIDefine* define,
ub4 iter,
dvoid** bufpp,
ub4** alenpp,
ub1* piecep,
dvoid** indpp,
ub2** rcodepp)
RET_LEN4 = sizeof(OCILobLocator*);
*bufpp = FETCH_BUFFER_1[iter];
*alenpp = &RET_LEN4;
*piecep = OCI_ONE_PIECE;
*indpp = IND_BUFFER_1 + iter;
*rcodepp = ERROR_BUFFER_1 + iter;
//std::cout << "iter: " << iter << std::endl;
return OCI_CONTINUE;
int define_column(
OCIEnv* environment_handle,
OCISvcCtx* svc_handle,
OCIStmt* stmt_handle,
OCIError* error_handle,
OCIDefine** define_handle,
unsigned long pos,
long oci_type,
unsigned long fetch_size,
OCILobLocator** buf,
char* ind_buf,
ub2* err_buf)
static const char* FUN = "define_column()";
sword result;
if(oci_type == SQLT_BLOB)
::memset(buf, 0, fetch_size * 1024);
for(int i = 0; i < 1024; ++i)
if((result = OCIDescriptorAlloc(
(dvoid*)environment_handle,
(dvoid**)&buf[i],
(ub4)OCI_DTYPE_LOB,
(size_t)0,
(dvoid**)0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIDescriptorAlloc", result, error_handle);
ub2 size = 0;
OCIDescriptorPtr<OCIParam, OCI_DTYPE_PARAM> param_handle;
// ub2 oci_data_type = 0;
if((result = OCIParamGet(
stmt_handle,
OCI_HTYPE_STMT,
error_handle,
reinterpret_cast<void**>(&param_handle.fill()),
pos)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIParamGet", result, error_handle);
if((result = OCIAttrGet(
param_handle.get(),
OCI_DTYPE_PARAM,
&size,
0,
OCI_ATTR_DATA_SIZE,
error_handle)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrGet", result, error_handle);
if((result = OCIDefineByPos(
stmt_handle,
define_handle,
error_handle,
pos,
# ifdef _DYN
0,
-1,
#else
buf,
fetch_size,
#endif
oci_type,
ind_buf,
0,
err_buf, // ptr to array of column-level return codes
# ifdef _DYN
OCI_DYNAMIC_FETCH
# else
OCI_DEFAULT
# endif
)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
# ifdef _DYN
if((result = OCIDefineDynamic(
*define_handle,
error_handle,
0,
oci_blob_callback)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
# endif
return 0;
int define_columns(
OCIEnv* environment_handle,
OCISvcCtx* svc_handle,
OCIStmt* stmt_handle,
OCIError* error_handle)
static const char* FUN = "define_columns()";
define_handle_1 = 0;
int pos = 1;
::memset(ERROR_BUFFER_1, 0, 1024 * sizeof(ERROR_BUFFER_1[0]));
define_column(
environment_handle,
svc_handle,
stmt_handle,
error_handle,
&define_handle_1,
pos++,
SQLT_BLOB,
sizeof(OCILobLocator*),
FETCH_BUFFER_1,
IND_BUFFER_1,
ERROR_BUFFER_1);
return 0;
int execute_select(
const char* db,
const char* user,
const char* password)
static const char* FUN = "execute_select()";
const unsigned long FETCH_COUNT = 1024;
OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
connect(
environment_handle.get(),
db,
user,
password,
error_handle,
server_handle,
session_handle,
svc_context_handle);
OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
sword result;
if((result = OCIHandleAlloc(
environment_handle.get(),
(void**)&stmt_handle.fill(),
OCI_HTYPE_STMT,
0,
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
const char QUERY[] = "SELECT text FROM ADSERVERTEST_BLOB";
ub4 rows = 0;
if((result = OCIAttrSet(
stmt_handle.get(),
OCI_HTYPE_STMT,
(dvoid *)&rows,
(ub4)sizeof(ub4),
OCI_ATTR_PREFETCH_ROWS,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(
FUN, "OCIAttrSet(OCI_ATTR_PREFETCH_ROWS)", result, error_handle.get());
if((result = OCIStmtPrepare(
stmt_handle.get(),
error_handle.get(),
(text*)QUERY,
strlen(QUERY),
OCI_NTV_SYNTAX,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
ub2 stmt_type;
if((result = OCIAttrGet(
stmt_handle.get(),
OCI_HTYPE_STMT,
&stmt_type,
0,
OCI_ATTR_STMT_TYPE,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
ub4 prev_fetched = 0;
while((result = OCIStmtExecute(
svc_context_handle.get(),
stmt_handle.get(),
error_handle.get(),
0,
0,
0,
0,
OCI_DEFAULT)) != OCI_SUCCESS)
if(result != OCI_STILL_EXECUTING)
throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
define_columns(
environment_handle.get(),
svc_context_handle.get(),
stmt_handle.get(),
error_handle.get());
ub4 all_fetched_count = 0;
while(true)
while((result = OCIStmtFetch2(
stmt_handle.get(),
error_handle.get(),
FETCH_COUNT,
OCI_FETCH_NEXT,
1,
OCI_DEFAULT)) == OCI_STILL_EXECUTING
# ifdef _DYN
// || result == OCI_NEED_DATA
# endif
if (result != OCI_SUCCESS &&
result != OCI_NO_DATA &&
result != OCI_SUCCESS_WITH_INFO)
std::cerr << FUN << ": can't make OCIStmtFetch2: status = " << result;
std::cerr << ", message = '";
text err_buf[1024] = "";
sb4 err_code = 0;
OCIErrorGet(
error_handle.get(),
(ub4)1,
0,
&err_code,
err_buf,
sizeof(err_buf),
(ub4)OCI_HTYPE_ERROR);
std::cerr << err_buf << "', error code = " << err_code << ", row errors: ";
for(const ub2* cur = ERROR_BUFFER_1;
cur < ERROR_BUFFER_1 + 1024; ++cur)
if(*cur)
std::cerr << "#" << (cur - ERROR_BUFFER_1) << ": " <<
*cur << std::endl;
ub4 fetched_count = 0;
if((result = OCIAttrGet (
stmt_handle.get(),
OCI_HTYPE_STMT,
&fetched_count,
0,
OCI_ATTR_ROW_COUNT,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
all_fetched_count += fetched_count;
if(fetched_count > 0)
for(unsigned long i = 0; i < fetched_count - 1; ++i)
ub4 lob_size;
while((result = OCILobGetLength(
svc_context_handle.get(),
error_handle.get(),
FETCH_BUFFER_1[i],
&lob_size)) == OCI_STILL_EXECUTING)
if(result != OCI_SUCCESS)
throw_oci_error(FUN, "OCILobGetLength", result, error_handle.get());
std::cout << "#" << i << ": ind = " << (unsigned long)IND_BUFFER_1[i] <<
", len = " << lob_size << std::endl;
if(fetched_count - prev_fetched < FETCH_COUNT)
break;
prev_fetched = fetched_count;
clear_blob_buf(
FETCH_BUFFER_1,
sizeof(OCILobLocator*));
while((result = OCIStmtFetch(
stmt_handle.get(),
error_handle.get(),
0,
OCI_FETCH_NEXT,
OCI_DEFAULT)) == OCI_STILL_EXECUTING
disconnect(
environment_handle.get(),
error_handle.get(),
server_handle.get(),
session_handle.get(),
svc_context_handle.get());
return 0;
int execute_update(
const char* db,
const char* user,
const char* password)
static const char* FUN = "execute_update()";
OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
connect(
environment_handle.get(),
db,
user,
password,
error_handle,
server_handle,
session_handle,
svc_context_handle);
OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
for(int i = 0; i < 1000; ++i)
sword result;
if((result = OCIHandleAlloc(
environment_handle.get(),
(void**)&stmt_handle.fill(),
OCI_HTYPE_STMT,
0,
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
std::ostringstream sql;
std::string str;
std::string et("\xEB\xB2\x88");
unsigned long rep = ::rand() % 500 + 1;
str.reserve(rep*et.size());
for(unsigned long ei = 0; ei < rep; ++ei)
str.append(et);
sql << "BEGIN " <<
"UPDATE ADSERVERTEST_BLOB SET text = "
"utl_raw.cast_to_raw('" << str << "') "
"WHERE id = " << i <<
"END;";
if((result = OCIStmtPrepare(
stmt_handle.get(),
error_handle.get(),
(text*)sql.str().c_str(),
sql.str().length(),
OCI_NTV_SYNTAX,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
while((result = OCIStmtExecute(
svc_context_handle.get(),
stmt_handle.get(),
error_handle.get(),
1,
0,
0,
0,
OCI_DEFAULT)) != OCI_SUCCESS)
if(result != OCI_STILL_EXECUTING)
throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
disconnect(
environment_handle.get(),
error_handle.get(),
server_handle.get(),
session_handle.get(),
svc_context_handle.get());
return 0;
void* select_thread(void* ctx)
while(true)
execute_select(
"//oraclept.ocslab.com/addbpt.ocslab.com",
"bs_unittest_4",
"adserver");
// std::cout << "select finished" << std::endl;
return ctx;
void* update_thread(void* ctx)
while(true)
execute_update(
"//oraclept.ocslab.com/addbpt.ocslab.com",
"bs_unittest_4",
"adserver");
// std::cout << "update finished" << std::endl;
return ctx;
int main()
static const char* FUN = "main()";
sword result;
// allocate an environment handle
if((result = OCIEnvCreate(
&environment_handle.fill(),
OCI_OBJECT | OCI_THREADED,
0, // context
0, // malloc
0, // realloc
0, // free
0, // extra memory to allocate
0) // pointer to user-memory
) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIEnvCreate", result, 0);
pthread_t th1, th2;
pthread_create(&th1, 0, select_thread, 0);
pthread_create(&th2, 0, update_thread, 0);
pthread_join(th1, 0);
pthread_join(th2, 0);
return 0;
Edited by: user13011391 on 20.04.2010 5:50
Edited by: user13011391 on 20.04.2010 6:00
Edited by: user13011391 on 20.04.2010 6:15

Hi all.
I have problem:
I try select BLOB field into OCILobLocator* buffer in Non Blocking mode, and receive 'ORA-03106: fatal two-task communication protocol error' sometimes.
Details:
Application contains two threads : 1. select blob field, 2. update it.
I tried separate update and select to different apps (and run its in one time) - problem reproduced.
problem reproduced for OCIStmtFetch and OCIStmtFetch2.
If disable non blocking mode - problem disappear.
if error appear - record level error code contains 1405. Need wait few minutes for error message appearing (~1 minute in my case).
Using of OCI_DEFAULT in OCIDefineByPos instead OCI_DYNAMIC_FETCH don't solve problem.
I use oracle server and client library with version 10.2.0.4
Output sample:
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #877: 1405
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #54: 1405
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #877: 1405
execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
', error code = 3106, row errors: #54: 1405
Can anybody help me ?
m.b. exists workaround ?
#include <iostream>
#include <sstream>
#include <assert.h>
#include <oci.h>
#define _DYN 1
before run this test run next sql at DB:
CREATE TABLE ADSERVERTEST_BLOB(id NUMBER(10), text BLOB);
BEGIN
FOR i IN 0..999 LOOP
INSERT INTO ADSERVERTEST_BLOB(id, text) VALUES(i, utl_raw.cast_to_raw('init'));
END LOOP;
END;
template<typename Type, unsigned long TypeId>
class OCIHandlePtr
public:
OCIHandlePtr(): handle_(0) {}
OCIHandlePtr(Type* handle): handle_(handle) {}
~OCIHandlePtr()
reset(0);
void reset(Type* handle)
if(handle_)
sword result;
if((result = OCIHandleFree(
handle_,
TypeId)) != OCI_SUCCESS)
assert(0);
std::cerr << "Can't make OCIHandleFree" << std::endl;
handle_ = handle;
Type* get()
return handle_;
Type*& fill()
reset(0);
return handle_;
private:
Type* handle_;
template<typename Type, unsigned long TypeId>
class OCIDescriptorPtr
public:
OCIDescriptorPtr(): handle_(0) {}
OCIDescriptorPtr(Type* handle): handle_(handle) {}
~OCIDescriptorPtr()
reset(0);
void reset(Type* handle)
if(handle_)
sword result;
if((result = OCIDescriptorFree(
handle_,
TypeId)) != OCI_SUCCESS)
std::cerr << "Can't make OCIDescriptorFree" << std::endl;
handle_ = handle;
Type* get()
return handle_;
Type*& fill()
reset(0);
return handle_;
private:
Type* handle_;
void throw_oci_error(
const char* fun,
const char* oci_op,
long status,
OCIError* oci_error_handler,
const char* query = 0)
std::cerr << fun << ": can't make " << oci_op << ": status = " << status;
if(status == OCI_SUCCESS_WITH_INFO ||
status == OCI_ERROR)
std::cerr << ", message = '";
text err_buf[1024] = "";
sb4 err_code = 0;
OCIErrorGet(
oci_error_handler,
(ub4)1,
0,
&err_code,
err_buf,
sizeof(err_buf),
(ub4)OCI_HTYPE_ERROR);
std::cerr << err_buf << "', error code = " << err_code;
exit(1);
if(query)
std::cerr << ", sql = " << query;
OCIHandlePtr<OCIEnv, OCI_HTYPE_ENV> environment_handle;
void connect(
OCIEnv* environment_handle,
const char* db,
const char* user,
const char* password,
OCIHandlePtr<OCIError, OCI_HTYPE_ERROR>& error_handle,
OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER>& server_handle,
OCIHandlePtr<OCISession, OCI_HTYPE_SESSION>& session_handle,
OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX>& svc_context_handle)
static const char* FUN = "connect()";
sword result;
// allocate an error handle
if((result = OCIHandleAlloc(
environment_handle,
(void **) &error_handle.fill(),
OCI_HTYPE_ERROR,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// allocate a server handle
if((result = OCIHandleAlloc(
environment_handle,
(void **) &server_handle.fill(),
OCI_HTYPE_SERVER,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
if((result = OCIServerAttach(
server_handle.get(),
error_handle.get(),
(text*)db,
strlen(db),
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIServerAttach", result, error_handle.get());
// allocate a service handle
if((result = OCIHandleAlloc(
environment_handle,
(void **) &svc_context_handle.fill(),
OCI_HTYPE_SVCCTX,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// set the server attribute in the service context handle
if((result = OCIAttrSet(
svc_context_handle.get(),
OCI_HTYPE_SVCCTX,
server_handle.get(),
sizeof(OCIServer*),
OCI_ATTR_SERVER,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// allocate a user session handle
if((result = OCIHandleAlloc(
environment_handle,
(void **)&session_handle.fill(),
OCI_HTYPE_SESSION,
0, // extra memory to allocate
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
// set username and password attributes in user session handle
if((result = OCIAttrSet(
session_handle.get(),
OCI_HTYPE_SESSION,
(text*)user,
strlen(user),
OCI_ATTR_USERNAME,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
if((result = OCIAttrSet(
session_handle.get(),
OCI_HTYPE_SESSION,
(text*)password,
strlen(password),
OCI_ATTR_PASSWORD,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
// start the session
if((result = OCISessionBegin(
svc_context_handle.get(),
error_handle.get(),
session_handle.get(),
OCI_CRED_RDBMS,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCISessionBegin", result, error_handle.get());
// set the user session attribute in the service context handle
if((result = OCIAttrSet(
svc_context_handle.get(),
OCI_HTYPE_SVCCTX,
session_handle.get(),
sizeof(OCISession*),
OCI_ATTR_SESSION,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
ub1 attr_value = 1;
if((result = OCIAttrSet(
server_handle.get(),
OCI_HTYPE_SERVER,
&attr_value,
sizeof(attr_value),
OCI_ATTR_NONBLOCKING_MODE,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
void disconnect(
OCIEnv* environment_handle,
OCIError* error_handle,
OCIServer* server_handle,
OCISession* session_handle,
OCISvcCtx* svc_context_handle)
static const char* FUN = "disconnect()";
sword result;
if((result = OCISessionEnd(
svc_context_handle,
error_handle,
session_handle,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCISessionEnd", result, error_handle);
if((result = OCIServerDetach(
server_handle,
error_handle,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIServerDetach", result, error_handle);
OCILobLocator* FETCH_BUFFER_1[10000*1024];
char IND_BUFFER_1[10000*1024];
ub2 ERROR_BUFFER_1[1024];
OCIDefine* define_handle_1;
void clear_blob_buf(
OCILobLocator** buf,
unsigned long fetch_size)
for(unsigned long i = 0; i < 1024; ++i)
OCIDescriptorFree(
buf,
(ub4)OCI_DTYPE_LOB);
::memset(buf, 0, fetch_size * 1024);
uint32_t RET_LEN4;
sb4 oci_blob_callback(
dvoid* ctx,
OCIDefine* define,
ub4 iter,
dvoid** bufpp,
ub4** alenpp,
ub1* piecep,
dvoid** indpp,
ub2** rcodepp)
RET_LEN4 = sizeof(OCILobLocator*);
*bufpp = FETCH_BUFFER_1[iter];
*alenpp = &RET_LEN4;
*piecep = OCI_ONE_PIECE;
*indpp = IND_BUFFER_1 + iter;
*rcodepp = ERROR_BUFFER_1 + iter;
//std::cout << "iter: " << iter << std::endl;
return OCI_CONTINUE;
int define_column(
OCIEnv* environment_handle,
OCISvcCtx* svc_handle,
OCIStmt* stmt_handle,
OCIError* error_handle,
OCIDefine** define_handle,
unsigned long pos,
long oci_type,
unsigned long fetch_size,
OCILobLocator** buf,
char* ind_buf,
ub2* err_buf)
static const char* FUN = "define_column()";
sword result;
if(oci_type == SQLT_BLOB)
::memset(buf, 0, fetch_size * 1024);
for(int i = 0; i < 1024; ++i)
if((result = OCIDescriptorAlloc(
(dvoid*)environment_handle,
(dvoid**)&buf[i],
(ub4)OCI_DTYPE_LOB,
(size_t)0,
(dvoid**)0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIDescriptorAlloc", result, error_handle);
ub2 size = 0;
OCIDescriptorPtr<OCIParam, OCI_DTYPE_PARAM> param_handle;
// ub2 oci_data_type = 0;
if((result = OCIParamGet(
stmt_handle,
OCI_HTYPE_STMT,
error_handle,
reinterpret_cast<void**>(&param_handle.fill()),
pos)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIParamGet", result, error_handle);
if((result = OCIAttrGet(
param_handle.get(),
OCI_DTYPE_PARAM,
&size,
0,
OCI_ATTR_DATA_SIZE,
error_handle)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrGet", result, error_handle);
if((result = OCIDefineByPos(
stmt_handle,
define_handle,
error_handle,
pos,
# ifdef _DYN
0,
-1,
#else
buf,
fetch_size,
#endif
oci_type,
ind_buf,
0,
err_buf, // ptr to array of column-level return codes
# ifdef _DYN
OCI_DYNAMIC_FETCH
# else
OCI_DEFAULT
# endif
)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
# ifdef _DYN
if((result = OCIDefineDynamic(
*define_handle,
error_handle,
0,
oci_blob_callback)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
# endif
return 0;
int define_columns(
OCIEnv* environment_handle,
OCISvcCtx* svc_handle,
OCIStmt* stmt_handle,
OCIError* error_handle)
static const char* FUN = "define_columns()";
define_handle_1 = 0;
int pos = 1;
::memset(ERROR_BUFFER_1, 0, 1024 * sizeof(ERROR_BUFFER_1[0]));
define_column(
environment_handle,
svc_handle,
stmt_handle,
error_handle,
&define_handle_1,
pos++,
SQLT_BLOB,
sizeof(OCILobLocator*),
FETCH_BUFFER_1,
IND_BUFFER_1,
ERROR_BUFFER_1);
return 0;
int execute_select(
const char* db,
const char* user,
const char* password)
static const char* FUN = "execute_select()";
const unsigned long FETCH_COUNT = 1024;
OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
connect(
environment_handle.get(),
db,
user,
password,
error_handle,
server_handle,
session_handle,
svc_context_handle);
OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
sword result;
if((result = OCIHandleAlloc(
environment_handle.get(),
(void**)&stmt_handle.fill(),
OCI_HTYPE_STMT,
0,
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
const char QUERY[] = "SELECT text FROM ADSERVERTEST_BLOB";
ub4 rows = 0;
if((result = OCIAttrSet(
stmt_handle.get(),
OCI_HTYPE_STMT,
(dvoid *)&rows,
(ub4)sizeof(ub4),
OCI_ATTR_PREFETCH_ROWS,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(
FUN, "OCIAttrSet(OCI_ATTR_PREFETCH_ROWS)", result, error_handle.get());
if((result = OCIStmtPrepare(
stmt_handle.get(),
error_handle.get(),
(text*)QUERY,
strlen(QUERY),
OCI_NTV_SYNTAX,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
ub2 stmt_type;
if((result = OCIAttrGet(
stmt_handle.get(),
OCI_HTYPE_STMT,
&stmt_type,
0,
OCI_ATTR_STMT_TYPE,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
ub4 prev_fetched = 0;
while((result = OCIStmtExecute(
svc_context_handle.get(),
stmt_handle.get(),
error_handle.get(),
0,
0,
0,
0,
OCI_DEFAULT)) != OCI_SUCCESS)
if(result != OCI_STILL_EXECUTING)
throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
define_columns(
environment_handle.get(),
svc_context_handle.get(),
stmt_handle.get(),
error_handle.get());
ub4 all_fetched_count = 0;
while(true)
while((result = OCIStmtFetch2(
stmt_handle.get(),
error_handle.get(),
FETCH_COUNT,
OCI_FETCH_NEXT,
1,
OCI_DEFAULT)) == OCI_STILL_EXECUTING
# ifdef _DYN
// || result == OCI_NEED_DATA
# endif
if (result != OCI_SUCCESS &&
result != OCI_NO_DATA &&
result != OCI_SUCCESS_WITH_INFO)
std::cerr << FUN << ": can't make OCIStmtFetch2: status = " << result;
std::cerr << ", message = '";
text err_buf[1024] = "";
sb4 err_code = 0;
OCIErrorGet(
error_handle.get(),
(ub4)1,
0,
&err_code,
err_buf,
sizeof(err_buf),
(ub4)OCI_HTYPE_ERROR);
std::cerr << err_buf << "', error code = " << err_code << ", row errors: ";
for(const ub2* cur = ERROR_BUFFER_1;
cur < ERROR_BUFFER_1 + 1024; ++cur)
if(*cur)
std::cerr << "#" << (cur - ERROR_BUFFER_1) << ": " <<
*cur << std::endl;
ub4 fetched_count = 0;
if((result = OCIAttrGet (
stmt_handle.get(),
OCI_HTYPE_STMT,
&fetched_count,
0,
OCI_ATTR_ROW_COUNT,
error_handle.get())) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
all_fetched_count += fetched_count;
if(fetched_count > 0)
for(unsigned long i = 0; i < fetched_count - 1; ++i)
ub4 lob_size;
while((result = OCILobGetLength(
svc_context_handle.get(),
error_handle.get(),
FETCH_BUFFER_1[i],
&lob_size)) == OCI_STILL_EXECUTING)
if(result != OCI_SUCCESS)
throw_oci_error(FUN, "OCILobGetLength", result, error_handle.get());
std::cout << "#" << i << ": ind = " << (unsigned long)IND_BUFFER_1[i] <<
", len = " << lob_size << std::endl;
if(fetched_count - prev_fetched < FETCH_COUNT)
break;
prev_fetched = fetched_count;
clear_blob_buf(
FETCH_BUFFER_1,
sizeof(OCILobLocator*));
while((result = OCIStmtFetch(
stmt_handle.get(),
error_handle.get(),
0,
OCI_FETCH_NEXT,
OCI_DEFAULT)) == OCI_STILL_EXECUTING
disconnect(
environment_handle.get(),
error_handle.get(),
server_handle.get(),
session_handle.get(),
svc_context_handle.get());
return 0;
int execute_update(
const char* db,
const char* user,
const char* password)
static const char* FUN = "execute_update()";
OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
connect(
environment_handle.get(),
db,
user,
password,
error_handle,
server_handle,
session_handle,
svc_context_handle);
OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
for(int i = 0; i < 1000; ++i)
sword result;
if((result = OCIHandleAlloc(
environment_handle.get(),
(void**)&stmt_handle.fill(),
OCI_HTYPE_STMT,
0,
0)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
std::ostringstream sql;
std::string str;
std::string et("\xEB\xB2\x88");
unsigned long rep = ::rand() % 500 + 1;
str.reserve(rep*et.size());
for(unsigned long ei = 0; ei < rep; ++ei)
str.append(et);
sql << "BEGIN " <<
"UPDATE ADSERVERTEST_BLOB SET text = "
"utl_raw.cast_to_raw('" << str << "') "
"WHERE id = " << i <<
"END;";
if((result = OCIStmtPrepare(
stmt_handle.get(),
error_handle.get(),
(text*)sql.str().c_str(),
sql.str().length(),
OCI_NTV_SYNTAX,
OCI_DEFAULT)) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
while((result = OCIStmtExecute(
svc_context_handle.get(),
stmt_handle.get(),
error_handle.get(),
1,
0,
0,
0,
OCI_DEFAULT)) != OCI_SUCCESS)
if(result != OCI_STILL_EXECUTING)
throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
disconnect(
environment_handle.get(),
error_handle.get(),
server_handle.get(),
session_handle.get(),
svc_context_handle.get());
return 0;
void* select_thread(void* ctx)
while(true)
execute_select(
"//oraclept.ocslab.com/addbpt.ocslab.com",
"bs_unittest_4",
"adserver");
// std::cout << "select finished" << std::endl;
return ctx;
void* update_thread(void* ctx)
while(true)
execute_update(
"//oraclept.ocslab.com/addbpt.ocslab.com",
"bs_unittest_4",
"adserver");
// std::cout << "update finished" << std::endl;
return ctx;
int main()
static const char* FUN = "main()";
sword result;
// allocate an environment handle
if((result = OCIEnvCreate(
&environment_handle.fill(),
OCI_OBJECT | OCI_THREADED,
0, // context
0, // malloc
0, // realloc
0, // free
0, // extra memory to allocate
0) // pointer to user-memory
) != OCI_SUCCESS)
throw_oci_error(FUN, "OCIEnvCreate", result, 0);
pthread_t th1, th2;
pthread_create(&th1, 0, select_thread, 0);
pthread_create(&th2, 0, update_thread, 0);
pthread_join(th1, 0);
pthread_join(th2, 0);
return 0;
Edited by: user13011391 on 20.04.2010 5:50
Edited by: user13011391 on 20.04.2010 6:00
Edited by: user13011391 on 20.04.2010 6:15

Similar Messages

  • Sockets in non-blocking mode

    Hello Techies,
    How to set sockets in the non-blocking mode and what is the main use of setting sockets in non-blocking mode.
    regards,
    Ramu.

    Hello Techies,
    Thanks for u r replies,
    Finally i had understood how to use nio. But the problem is it is going into infinite loop. Here is my code.
    package networking;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.util.Iterator;
    public class testSocketChannel {
          * @param args
         public static ByteBuffer buf ;
         public static SocketChannel clientChannel;
         public static void main(String[] args) {
              // TODO Auto-generated method stub
                        try
                             Selector selector = Selector.open();
                         clientChannel = SocketChannel.open();
                      clientChannel.configureBlocking(false);
                      // Send a connection request to the server; this method is non-blocking
                      clientChannel.connect(new InetSocketAddress("localhost",90));
                      clientChannel.register(selector,clientChannel.validOps());
    //                Wait for events
                      while (true)
                          try {
                              // Wait for an event
                              selector.select();
                          } catch (IOException e) {
                              // Handle error with selector
                              //break;
                          // Get list of selection keys with pending events
                          Iterator it = selector.selectedKeys().iterator();
                          // Process each key at a time
                          //while (it.hasNext())
                               for(int i = 0;i<selector.selectedKeys().size();i++)
                              // Get the selection key
                              SelectionKey selKey = (SelectionKey)it.next();
                              // Remove it from the list to indicate that it is being processed
                              it.remove();
                              try
                          //  processSelectionKey(selKey);
                                    if (selKey.isValid() && selKey.isConnectable()) {
                                       // Get channel with connection request
                                       SocketChannel sChannel = (SocketChannel)selKey.channel();
                                       boolean success = sChannel.finishConnect();
                                       if (!success) {
                                           // An error occurred; handle it
                                           // Unregister the channel with this selector
                                           selKey.cancel();
                                   if (selKey.isValid() && selKey.isReadable()) {
                                       // Get channel with bytes to read
                                        clientChannel = (SocketChannel)selKey.channel();
                                       System.out.println("INSIDE reading");
                                       // See e174 Reading from a SocketChannel
                                       // Clear the buffer and read bytes from socket
    //                                 Clear the buffer and read bytes from socket
                                      // ByteBuffer byteBuffer = ByteBuffer.allocate( BUFSIZE );
                                       buf = ByteBuffer.allocateDirect(1024);
                                       int nbytes = clientChannel.read( buf );
                                       buf.flip();
                                       Charset charset = Charset.forName( "us-ascii" );
                                       CharsetDecoder decoder = charset.newDecoder();
                                       CharBuffer charBuffer = decoder.decode( buf );
                                       String result = charBuffer.toString();
                                   if (selKey.isValid() && selKey.isWritable()) {
                                       // Get channel that's ready for more bytes
                                       //SocketChannel sChannel = (SocketChannel)selKey.channel();
                                       System.out.println("INSIDE writting");
                                       // See e175 Writing to a SocketChannel
                                     String message = "hi"; 
                                      buf = ByteBuffer.wrap( message.getBytes()  );
                                       int nbytes = clientChannel.write( buf );
                                       System.out.println( "Wrote " + nbytes + " to channel." );
                              catch (IOException e) {
                                       // TODO: handle exception
                                   System.out.println("IOException"+e.getMessage());
                        catch (IOException ioe) {
                             // TODO: handle exception
                             System.out.println("IOException"+ioe.getMessage());
    }How to stop this infinite loop.
    Need quick replies.
    Ramu

  • SocketChannel in non-blocking mode

    invoke these channel's write(Buffer) method, it will return immediately,
    how to know when buffer data have been send completely

    You can't know this at all unless the peer sends an acknowledgement as part of your application protocol.

  • ORA-03118 two-task error while doing a non blocking OCI call

    Hi,
    I have an application that runs on Linux and uses OCI API (version 8.1.6).
    If I do the following in non blocking mode after polling about
    70 times I get the error:
    ORA-03118: two-task coroutine has invalid state
    do {
    call_cnt++;
    rtc = OCIStmtFetch(stmtptr->stmt, oracle_err, 1, OCI_FETCH_NEXT,
    OCI_DEFAULT);
    } while (rtc == OCI_STILL_EXECUTING);
    This doesn't happen all the time but it happens most often on big selects.
    Does anyone have any idea what is happening here?
    I have searched for related information but have come up dry. If anyone
    knows anything or maybe a better place to ask this question please tell me.
    Thanks,
    Barry
    null

    Ask your basis guys to increase the table space...
    check this thread...
    [Error : DBIF_RSQL_SQL_ERROR;
    --- Thanks...

  • Non-Blocking I/O Implementation Issue

    Hi All,
    I am trying out the latest JDK 1.4 java.nio.* package. I modified the NBTimeServer and wrote a client which connects to the NBTimeServer and tries to pass messages to and fro. I always succeed to pass on roundtrip of msgs and then Server blocks my client forever. I have modified NBTimeServer to accomodate one client only. Any help or comments on this would be really appreciated. Code is below. Feel free to try it out if want to see what I am trying to convey in this message.
    /*******Server Code*******/
    Modified this code to test mulitple to and fro msgs between client and server.
    Only one client will ever be able to connect to this server during life of a server.
    My point here is to demonstrate the to and fro comm between one client and one server
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.net.*;
    import java.util.*;
    import java.nio.charset.*;
    import java.util.regex.*;
    // Listen on a port for connections and write back the current time.
    public class NBTimeServer {
    private static final int DEFAULT_TIME_PORT = 8900;
    // Constructor with no arguments creates a time server on default port.
    public NBTimeServer() throws Exception {
         acceptConnections(this.DEFAULT_TIME_PORT);
    // Constructor with port argument creates a time server on specified port.
    public NBTimeServer(int port) throws Exception {
         acceptConnections(port);
    // Accept connections for current time. Lazy Exception thrown.
    private static void acceptConnections(int port) throws Exception {
         // Selector for incoming time requests
         Selector acceptSelector = SelectorProvider.provider().openSelector();
         Selector rwSelector = SelectorProvider.provider().openSelector();
         // Create a new server socket and set to non blocking mode
         ServerSocketChannel ssc = ServerSocketChannel.open();
         ssc.configureBlocking(false);
         // Bind the server socket to the local host and port
         InetAddress lh = InetAddress.getLocalHost();
         InetSocketAddress isa = new InetSocketAddress(lh, port);
         ssc.socket().bind(isa);
         // Register accepts on the server socket with the selector. This
         // step tells the selector that the socket wants to be put on the
         // ready list when accept operations occur, so allowing multiplexed
         // non-blocking I/O to take place.
         SelectionKey acceptKey = ssc.register(acceptSelector,
                             SelectionKey.OP_ACCEPT);
         int keysAdded = 0;
         // Here's where everything happens. The select method will
         // return when any operations registered above have occurred, the
         // thread has been interrupted, etc.
         while ((keysAdded = acceptSelector.select()) > 0) {
         // Someone is ready for I/O, get the ready keys
         Set readyKeys = acceptSelector.selectedKeys();
         Iterator i = readyKeys.iterator();
         // Walk through the ready keys collection and process date requests.
         while (i.hasNext()) {
              SelectionKey sk = (SelectionKey)i.next();
              i.remove();
              // The key indexes into the selector so you
              // can retrieve the socket that's ready for I/O
              ServerSocketChannel nextReady =
              (ServerSocketChannel)sk.channel();
              // Accept the date request and send back the date string
              Socket s = nextReady.accept();
                        SocketChannel sc = s.getChannel();
    System.out.println("Got client channel..");
              sc.configureBlocking(false);
              SelectionKey readKey = sc.register(rwSelector,
                             SelectionKey.OP_READ|SelectionKey.OP_WRITE);                     
              int count = 0;
    while(true) {
    if((count = rwSelector.select(1000L)) > 0) {
    Set readKeys = rwSelector.selectedKeys();
    Iterator i1 = readKeys.iterator();
    while(i1.hasNext()) {
    System.out.println("Loop in Iterator");
    SelectionKey sk1 = (SelectionKey)i1.next();
    i1.remove();
    if(sk1.isReadable()) {
    DataInputStream sin = new DataInputStream(new BufferedInputStream(s.getInputStream(), 4096));
    System.out.println(sin.readInt());
    if(sk1.isWritable()) {
    DataOutputStream sout = new DataOutputStream(new BufferedOutputStream(s.getOutputStream(), 4096));
    PrintWriter out = new PrintWriter(sout, true);
              Date now = new Date();
              out.println(now);
    // Entry point.
    public static void main(String[] args) {
         // Parse command line arguments and
         // create a new time server (no arguments yet)
         try {
              NBTimeServer nbt = new NBTimeServer();
         } catch(Exception e) {
              e.printStackTrace();          
    /******End Server Code********/
    /*****Begin Client Code********/
    import java.io.*;
    import java.net.*;
    import java.util.*;
    // Listen on a port for connections and write back the current time.
    public class NBTimeClient {
    private static final int DEFAULT_TIME_PORT = 8900;
    public static void main(String args[]) throws Exception {
    InetAddress lh = InetAddress.getLocalHost();
    Socket s = new Socket(lh, DEFAULT_TIME_PORT);
    DataInputStream din = new DataInputStream(new BufferedInputStream(s.getInputStream(), 4096));
    DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(s.getOutputStream(), 4096));
    //Read the time
    System.out.println(din.readLine());
    //send some junk which is read by server
    dout.writeInt(1299);
    dout.flush();
    //read time again -- I never get anything here and I am blocked here...
    System.out.println(din.readLine());
    //send some junk back to the server
    dout.writeInt(1299);
    dout.flush();
    s.close();
    /*******End Client Code**********/
    thanks,
    Xtrimity

    The reason it blocks forever is that you need to keep reusing your main select. That is where the non-blocking event will come from. Here is a bit of code that doesn't block forever.
    Tim
    http://tim.owlmountain.com
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.net.*;
    import java.util.*;
    import org.apache.log4j.*;
    public class NBServer3 {
    int _port = 4000;
    Selector _selector = null;
    ServerSocketChannel _selectableChannel = null;
    int _keysAdded = 0;
    static Category log =
    Category.getInstance(NBServer3.class.getName());
    static String QUIT_SERVER = "quit";
    public NBServer3() {
    public NBServer3( int port ) {
    this._port = port;
    public void initialize()
    throws IOException {
    this._selector = SelectorProvider.provider().openSelector();
    this._selectableChannel = ServerSocketChannel.open();
         this._selectableChannel.configureBlocking(false);
         InetAddress lh = InetAddress.getLocalHost();
         InetSocketAddress isa = new InetSocketAddress(lh, this._port );
         this._selectableChannel.socket().bind(isa);
    public void finalize()
    throws IOException {
    this._selectableChannel.close();
    this._selector.close();
    public void acceptConnections()
    throws IOException {
    Selects a set of keys whose corresponding channels are ready for I/O
    operations. This method performs a non-blocking selection operation.
    If no channels have become selectable since the previous selection
    operation then this method immediately returns zero.
    Returns:
    The number of keys, possibly zero, whose ready-operation sets
    were updated by the selection operation
    do {
    SelectionKey acceptKey =
    this._selectableChannel.register( this._selector,
    SelectionKey.OP_ACCEPT );
    log.debug( "Acceptor loop..." );
    while (( this._keysAdded = acceptKey.selector().select()) > 0 ) {
    log.debug( "Selector returned "
    + this._keysAdded + " ready for IO operations" );
    Set readyKeys = this._selector.selectedKeys();
    Iterator i = readyKeys.iterator();
    while (i.hasNext()) {
    SelectionKey key = (SelectionKey)i.next();
    i.remove();
    if ( key.isAcceptable() ) {
    ServerSocketChannel nextReady =
    (ServerSocketChannel)key.channel();
    log.debug( "Processing selection key read="
    + key.isReadable() + " write=" + key.isWritable() +
    " accept=" + key.isAcceptable() );
    Socket s = nextReady.accept();
    s.getChannel().configureBlocking( false );
    SelectionKey readKey =
    s.getChannel().register( this._selector,
    SelectionKey.OP_READ );
    readKey.attach( s );
    else if ( key.isReadable() ) {
    SelectableChannel nextReady =
    (SelectableChannel) key.channel();
    log.debug( "Processing selection key read="
    + key.isReadable() + " write=" + key.isWritable() +
    " accept=" + key.isAcceptable() );
    Socket socket = (Socket) key.attachment();
    BufferedReader in = new BufferedReader(
    new InputStreamReader( socket.getInputStream() ));
    String line = null;
    if ( (line = in.readLine() ) != null )
    log.debug( line );
    log.debug( "End acceptor loop..." );
    } while ( false ); //FIXIT tim this should be false. justa test
    public static void main( String[] args ) {
    BasicConfigurator.configure();
    NBServer3 nbServer = new NBServer3();
    try {
    nbServer.initialize();
    } catch ( IOException e ) {
    e.printStackTrace();
    System.exit( -1 );
    try {
    nbServer.acceptConnections();
    catch ( IOException e ) {
    e.printStackTrace();
    log.error( e );

  • SO timeout relevance in non-blocking NIO ServerSocketChannel

    I converted a threaded blocking server from using the standard blocking IO with a thread for each connection to using non-blocking NIO channels. Works great but I'm trying to understand the SO timeout relevance in the context of non-blocking NIO channels. Is there any relevance and should I set an SO timeout on the ServerSocket associated with a ServerSocketChannel and if so how should I handle it?

    No. Socket timeouts are for blocking mode. If you need timeouts in non-blocking mode you have to do them yourself, taking advantage of the Selector.select(long timeout) method and keeping track of activity times per channel yourself. You should use that select() method anyway, rather than just blocking indefinitely, as it gives you a chance to catch up on housekeeping, dead channels, etc. For example as a very naive approach if nothing happens in say a select timeout of 10 minutes you might want to close all accepted SocketChannels.

  • HTTP Web Proxy using Non Blocking IO

    Resolved Thanks................

    client.register(selector, SelectionKey.OP_READ
    | SelectionKey.OP_WRITE);OP_READ only at this stage. OP_WRITE is always 'ready' unless the socket send buffer is full, so your selector will just spin. Don't register OP_WRITE until you have something to write.
    ByteBuffer bferClient = ByteBuffer.allocate(4096);You're doing this every time around the loop, and you don't even know whether the key is readable yet. Do it when you accept a connection, and save it as the key attachment for that channel.
    client.configureBlocking(false);It's already in non-blocking mode. Why are you doing this again?
    try {
    if ((bytesRead = client.read(bferClient)) != -1) {
    bferClient.flip();
    String msgFromClient = new String(bferClient.array());new String(bferClient.array(), 0, bferClient.limit()-1), but you're assuming you got a complete command here. You may not have. That's another reason why you need a ByteBuffer per channel.
    channel.connect(socketAddress);You should do that in non-blocking mode, register the channel for OP_CONNECT, and let the select loop take care of finishing the connection.
    channel.write(bferClient);The incoming command was CONNECT. You don't write that upstream.
    if (!"".equals(msgFromClient.trim())) {
    int bytesReadServer;
    byte[] reply = new byte[4096];
    try {
    ByteBuffer bufferNIO = ByteBuffer.allocateDirect(1024);
    while ((channel.read(bufferNIO)) != -1) {
    bufferNIO.flip();
    client.write(bufferNIO);
    bufferNIO.clear();
    }And you don't do any of this here. You register the new channel for OP_CONNECT, then when you get that do finishConnect() and then register it for OP_READ, and proceed around your select loop. You also need to associate this channel with the channel you read the CONNECT from. So you really need a key attachment object for the original channel that contains its byte buffer and the upstream channel; similarly the upstream channel needs a key attachment that contains its buffer and its downstream channel. The effect of doing all this stuff here instead of around the select loop is that you are never getting back to the select loop: you are handling this one client here, in blocking mode, until the connection is dropped. Completely wrong.
    } catch (IOException e) {Hang on. If bytesRead was -1 you must close the channel.
    e.printStackTrace();And if you get any IOException here you must also close the channel.
    if (channel != null) {
    try {
    channel.close();This is a really strange place to close this channel.
    When you get all that fixed up, post your code and I'll tell you how to handle OP_WRITE.

  • NIO non-blocking i/o- Any advantages for UDP server??

    Hi,
    I am developing a classic UDP-based server which serves hundreds of clients simultaneously. After receiving a simple request from a client, the server replies with a simple response (messages are no larger than 50 bytes).
    What, if any non-blocking-related advantages would there be in using nio? Specifically, if I used select() without turning on non-blocking on the data channel, what do I lose?
    The architecture consists of only one socket for responding to client requests. It uses receive() and send(), not read()/write()/connect().
    Thanks in advance,
    Dan.

    >>
    What, if any non-blocking-related advantageswould
    there be in using nio? Specifically, if I used
    select() without turning on non-blocking on thedata
    channel, what do I lose?You cannot do this. The runtime will throw an
    IllegalBlockingModeException when you tried to
    register it.
    So in order to use select(), your registered channels must
    be in non-blocking mode? Why? That's just the way it is?
    So to conclude, using non-blocking mode provides no real advantage for
    my application. It is only required or else I would not be able to use
    select(), right? If so, what is so good about nio? Can you give an example that is similar to my application which would benefit from the non-blocking characteristic of nio?
    Thanks for your help so far...
    Daniel.
    >>
    The architecture consists of only one socket for
    responding to client requests. It uses receive()and
    send(), not read()/write()/connect().If you are only reading from one socket there are
    theoretical advantages to servicing requests on more
    than one thread, but you would not use non-blocking
    mode to do this.
    However I think some operating systems have
    performance problems when doing this. Look at this
    article under accept serialization:
    http://httpd.apache.org/docs/misc/perf-tuning.html
    The same problems may apply to multi-thread udp socket
    readers.

  • FileChannel.transferTo() using non-blocking SocketChannel

    I'm looking to use FileChannel.transfer(From/To) for performing file transfers over a network. On the uploading side I find that even though I set the SocketChannel to non-blocking mode, the loop manages to send files as large as 30MB in only a single transferTo() invocation. What I'm hoping for is to have a series of partial writes so that I might generate progress notifications, which does occur on the downloading side with transferFrom(). I don't think a file that large should be transferred in one pass so I'm thinking that this is caused by either some internal buffer allocation issue or a goof-up on my part.
    Thanks in advance for any input and here's the uploading code:
    public void upload( String fileName ) {
    FileInputStream fileStrm = null;
    FileChannel fileChan = null;
    FileLock fileLock = null;
    SocketChannel sockChan = null;
    Selector selector = null;
    try {
    // Lock the source file.
    file = new File( fileName );
    fileStrm = new FileInputStream( file );
    fileChan = fileStrm.getChannel();
    fileLock = fileChan.lock( 0L, Long.MAX_VALUE, true );
    // Open a server socket bound to an arbitrary port.
    servChan = ServerSocketChannel.open();
    servChan.socket().bind( new InetSocketAddress( 0 ) );
    // Wait for a single connection and close the server socket.
    sockChan = servChan.accept();
    servChan.close();
    sockChan.configureBlocking( false );
    selector = Selector.open();
    SelectionKey selectorKey = sockChan.register( selector, SelectionKey.OP_WRITE );
    // Loop until transfer has completed.
    int fileSize = ( int ) file.length();
    int sizeLeft = fileSize;
    while ( sizeLeft > 0 ) {
    // Wait for data to read, then transfer it.
    if ( selector.select() == 1 && selectorKey.isWritable() ) {
    sizeLeft -= ( int ) fileChan.transferTo( fileSize - sizeLeft, sizeLeft, sockChan );
    // Generate a progress notification here such as:
    // monitor.bytesTransferred( fileSize - sizeLeft );
    catch ( IOException ex ) {
    ex.printStackTrace();
    finally {
    try {
    // Cleanup.
    if ( selector != null )
    selector.close();
    if ( sockChan != null )
    sockChan.close();
    if ( fileLock != null )
    fileLock.release();
    if ( fileChan != null )
    fileChan.close();
    if ( fileStrm != null )
    fileStrm.close();
    catch ( IOException ex ) {
    ex.printStackTrace();
    -Edwin

    Actually, the sending process appears way ahead of the receiving one, where the send seems to finish in a blink while the receive takes several seconds to complete. In other words, the transferTo() completes in one loop, while the transferFrom() performs many with delays in between. I'd guess all that data is sitting in some large outbound buffer at the sender, which would explain why it seems to finish too quickly. If I split the send into smaller chunks, the two sides run quite nearly at the same pace as expected.
    The receiver already sleeps by way of a select() against a non-blocking SocketChannel, so I'll try reducing the buffer sizes as you suggest.

  • Non blocking stored proc call

    HI
    I have written a c application using OCI which can call stored proc. but that is using blocking call. Is it possible to call stored proc in non blocking mode? So that I can receive output in call back function. Actually stored proc take much time to execute can I associate some Subscription callback-function with my stored proc call. Any idea?
    Thanks
    Kamran

    If you want to do non-blocking calls in OCI, you just need to set the server handle (svrhp below) attribute:
    sb2 polling=1;
    OCIAttrSet((dvoid *)svrhp,
    (ub4)OCI_HTYPE_SERVER,
    (dvoid *)&polling,
    (ub4)0,
    (ub4)OCI_ATTR_NONBLOCKING_MODE,
    (OCIError *) errhp);
    And then you call you OCIExecute() as you would in blocking mode. The difference is that instead of blocking until the call is done on the server, it always returns immediately. So instead of calling it just once per statement and checking the return code, you must keep calling OCIExecute() until it does not equal OCI_STILL_EXECUTING. When the proc is done, the final call to OCIExecute() will then be OCI_SUCCESS, OCI_ERROR, whatever happened.

  • Non-blocking SocketChannels

    I'm trying to learn how to use non-blocking socket channles, but I haven't found much info (nor luck) so far.
    To learn, I'm building a server and a client. The server accepts input from the clients and process it in only one thread. The clients should send Objects to the server, and the server process them and return the result also as an Object. For this, I'm trying to use ObjectOutputStream and ObjectInputStream.
    The problem I don't know how to solve is that the SocketChannel is in non-bolcking mode, so I can't use their input/output streams (I get a IllegalBlockingModeException). In the server process loop I can reconfigure the SocketChannel to blocking mode to be able to read the Object, but I can't configure it to non-blocking mode again because I get a CancelledKeyException.
    Does anyone know how to work with InputStreams and non-blocking channels? Or where to find more info about it?
    Here are the relevant part of the server code:
    Set ready = selector.selectedKeys();
    Iterator i = ready.iterator();
    while (i.hasNext()) {
       try {
          SelectionKey sk = i.next();
          i.remove();
          if (sk.isAcceptable()) {
             ServerSocketChannel ssc = (ServerSocketChannel)sk.channel();
             SocketChannel sc = ssc.accept();
             sc.configureBlocking(false);
             sc.register(selector, SelectionKey.OP_READ);
          } else if (sk.isReadable()) {
             SocketChannel sc = (SocketChannel)sk.channel();
             // PROBLEM: If the channel is in non-blocking mode
             // I cannot use InputStreams
             sk.cancel();
             sc.configureBlocking(true);
             // Read the object sent by the client
             ObjectInputStream in = new ObjectInputStream(Channels.newInputStream(sc));
             Object o = in.readObject();
             // PROBLEM: Can't put the channel back to non-blocking mode
             sc.configureBlocking(false);
             sc.register(selector, SelectionKey.OP_READ); // CancelledKeyException
       } catch (...){
    }

    In my client, this is working fine:
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    for (int i = 0; i < 30000; i++) {
       oos = new ObjectOutputStream(sc.socket().getOutputStream());
       oos.writeObject(object);
       oos.flush();
       ois = new ObjectInputStream(sc.socket().getInputStream());
       Object o = ois.readObject();
    }But trying to do it like this throws a StreamCorruptedException at the server side.
    ObjectOutputStream oos = new ObjectOutputStream(sc.socket().getOutputStream());
    ObjectInputStream ois = new ObjectInputStream(sc.socket().getInputStream());
    for (int i = 0; i < 30000; i++) {
       oos.writeObject(object);
       oos.flush();
       Object o = ois.readObject();
    }Do you know why?

  • OCCI and non-blocking

    I'd like to use the OCCI interface in a non-blocking mode. Does anyone have any experience with this? Looks like I need to use a combo of OCI and OCCI calls to set the OCI_HTYPE_SERVER handle with the OCI_ATTR_NONBLOCKING MODE. However, my stmt->executeQuery() method seems to be throwing an exceptions, which I would have though would have been the OCI_STILL_EXECUTING error, but it's not. The exeception is an "ORA-32103 error from OCI call". If I continue to do another stmt->executeQuery(), I eventually get an access exception.
    Anyone have any code snippets using OCCI in non-blocking mode?

    I use threads. ACE/TAO to be precise.
    I have singleton class that manages the Oracle environment and connection as well as being a statement
    factory.
    Just have a thread perform your stmt->executeXXX() method and you will not need to worry about non-blocking.
    That's how I do it and it works well.

  • How to handle write errors in non blocking sockets

    Hi,
    I'm using sockets registered with a Selector for read operations. I've seen code examples that put the SocketChannel in non blocking mode before registering it with the selector, and in fact not doing so would cause an IllegalBlockingModeException to be thrown.
    My problem is that I can't handle write errors. The call to write() returns inmediately without throwing any exception. Even worse, when the network timeout expires the selector wakes up and I get an exception on read(). So I can't tell the difference between a real read error and a write error.
    What can I do? Is there a magic method I haven't heard about?
    Thanks

    ejp wrote:
    OK, so what happens is this: you write from your ByteBuffer; if there is room in the socket send buffer, the data is transferred and the transfer count is returned. (If there isn''t, the write returns zero and nothing has happened.) Your application code then continues. Meanwhile TCP is trying to send the data in the send buffer and get an ACK from the peer. If the peer is down as per your test, eventually those write attempts will time out. You will then get a connection reset exception on the next read or write.
    Even worse, when the network timeout expires the selector wakes upCorrect, to tell you there is an error condition pending. This is good, not bad.You're right. This way my program can know that something happened.
    But I still don't understand what the difference between a failed write() and a failed read() is. I mean, the error condition may appear during a send attempt, or it may appear after sending. In both cases I get an error when trying to read. How can my program know if data have been received by the other end?
    Do I have to implement ACK messages in the application level protocol??? It'd be nice if TCP could do this for me...

  • Non-blocking io socket

    If you have a connection to on a non-blocking socket channel will the socket, is it possible that it will stop streaming all the data available into the buffer? If so how can you check that this has happened?
    If you buffer being used by the socket is full how can make sure the streaming stops so you can drain the buffer and get the remaining data without losing it from the channel.
    How can you check to see if a channel has no more data to give?
    Thank you.

    The sender's write method will block in blocking mode, or return zero in non-blocking mode, when the target's receive buffer and the sender's send buffer are both full. This is the only flow control available unless you implement something yourself. The only way to tell whether you have read everything the other end is sending is by getting an EOF when the other end closes the socket, unless you build something into your application protocol.

  • Non-blocking SocketChannel and close - huh?

    It looks like closing a socketchannel that is in non-blocking mode can result in a dead drop of the connection, with some bytes that have already been sent and accepted (as in, 'consumed' from the buffer) being completely dropped.
    In fact, I'm generally confused: Actual C non-blocking code has a similar setup for 'close' as you can see in SocketChannel's OP_CONNECT behaviour - just because you want to connect the socket doesn't mean it magically happends without blocking. Wait for a ready flag, then try again.
    It should work the same way with close (you try to close, but it may not be possible without blocking).
    Is this a huge gaping bug that no one quite figured out just yet, or did I miss something? I loathe to turn on linger, as that's just a crapshoot (you never know if it actually gets through. You could run into funny surprises once the server gets a bit busy. I'd rather not) and tends to cause massive leaks on linux, at least according to some google searches.
    There seems to be slightly better performance (in that I have always received all data sofar) if I close the socket instead of the channel (socketChannel.socket().close() instead of socketChannel.close()) - but this has been a random attempt at 'making it work', and I can't find any documentation that backs up that this will DEFINITELY not lose any information without letting me know somehow. That still sounds impossible with this approach.

    Actual C non-blocking code has a similar setup for
    'close' as you can see in SocketChannel's
    OP_CONNECT behaviour ...No it doesn't. I don't know what you mean by this.
    Closing a socket is asynchronous, but it shouldn't lose any data - if the data can be delivered it will be, followed by the FIN. You don't know when it is delivered, and you don't get to hear about any errors such as an RST coming from the other end, say if it decided to close before reading all the data, or if some intermediate router hung you up.
    I'm wondering if you are really dealing with all the short write and zero length write possibilities, i.e. whether the data isn't really still in your output buffer. Don't wish to teach you to suck eggs but there are some subtleties here.
    Setting a positive linger timeout doesn't really help because Java doesn't tell you if the timeout expired. (I only asked for this about four years ago). You get to wait while any pending data is delivered, but you still have to guess about whether it all went or the timeout expired, and the behaviour after the timeout expires is platform-dependent: some (Windows) issue an RST, others (Unix) keep trying.
    Blocking or non-blocking mode shouldn't make any difference to this (except that Linux will block on a positive linger timeout even in non-blocking mode, which is wrong), and whether you close the channel or the socket is immaterial as one calls the other anyway.
    The reason why OP_CONNECT is different in blocking/non-blocking modes is that in blocking mode it won't return until the SYN-ACK is received, while in non-blocking mode it just sends the SYN and relies on you calling connect() again (at the C level) to collect the SYN-ACK, or not - this is what finishConnect() tells you.
    tends to cause massive leaks on linux, at least
    according to some google searchesIt can't, unless you are referring to the Helix client thing, which appears to be just a badly designed C++ class library with, for some reason, its own linger implementation outside the kernel.

Maybe you are looking for

  • Processing Inbound IDOC's from FTP.

    Hi,          I have an issue where IDOC's (WPUBON01 & DEBMAS01) are being saved in ftp folder and once these IDOC's are saved, we have to process it in SAP System, i would like to know the simple way of having these IDOC's processed in Unix based SAP

  • Syncing contacts from iPhone back to iMac (Entourage)

    Briefly, after both my Time Machine and hard drive failed, I lost all my data. My Entourage contacts re-main on my iPhone, and I want to sync them back to Entourage. I understand the process of "merging,"but I have run into a few obstacles: I am usin

  • Why can Firefox not show ALT Tex on its web pages

    I cannot get Firefox to show ALT Tex when the mouse passes over links ect. I do not have this problem with Internet Explorer. Please help me on this matter, as a web designer I would like this feture to work in Firefox.

  • Writing metadata to originals is corrupting my files.

    Hey guys, I am using Aperture 3.3 with 10.7.4. I am importing my files, but they are not being copied into the library. I am leaving them where they are. Next I add keywords to them and then use the command 'Write IPTC metadata to originals'. Doing t

  • Firefox has been hijacked by Babylon Search, how do I get rid of it/

    I did not add Babylon Search. I deleted it from Add & Remove programs. It's gone from the list, but is still in Firefox. I removed it from Add-ons in Firefox. But it's still there. I've run ConboFix, but it's still there. How do I get rid of it?