클라이언트 API
본 장은 클라이언트 개발에 사용되는 API에 대해서 설명한다.
1. 개요
다음은 클라이언트에서 사용하는 함수에 대한 설명이다. 함수에 대한 자세한 사항은 Tmax 안내서 중 Tmax Reference Guide를 참고한다.
-
연결 및 해제
함수 설명 클라이언트를 Tmax 시스템에 연결한다.
클라이언트에서 Tmax 시스템과의 연결을 해제한다.
-
동기형 통신
함수 설명 클라이언트가 서비스를 요청하고 응답이 올 때까지 기다리는 동기형 통신 함수이다.
-
비동기형 통신
함수 설명 클라이언트에서 서비스를 요청하고 바로 반환한다.
tpacall에 의해서 보낸 요청에 대한 응답 버퍼의 데이터를 받는다.
서버와 클라이언트의 응답을 취소한다.
-
대화형 통신
함수 설명 연결을 설정하고 통신을 시작한다.
연결 컨트롤을 가진 곳에서 메시지를 보낼 때 사용한다.
연결이 설정된 후 연결 컨트롤을 가지지 않은 쪽에서 데이터를 받고자 할 때 사용한다.
서버와 클라이언트에서 대화형 통신 연결 종료한다.
-
비요청 메시지 처리
함수 설명 클라이언트에서 사용되는 함수로 비요청 수신 메시지를 처리하는 루틴 설정한다.
클라이언트의 요청없이 일방적으로 전달받은 메시지를 처리한다.
-
타임아웃 변경
함수 설명 서버와 클라이언트에서 사용되는 함수로 블로킹(blocking) 타임아웃 시간을 설정한다.
서비스 타임아웃 시간을 서비스 안에서 호출하여 설정한다.
-
버퍼 관리
함수 설명 서버와 클라이언트에서 버퍼를 할당한다.
서버와 클라이언트에서 버퍼를 재할당한다.
서버와 클라이언트에서 버퍼에 할당된 메모리를 해제한다.
서버와 클라이언트에서 사용되는 함수로 버퍼의 유형 및 하위 유형에 대한 정보를 제공한다.
-
트랜잭션 관리
함수 설명 서버와 클라이언트에서 사용하는 함수로 트랜잭션을 시작한다.
서버와 클라이언트에서 사용하는 함수로 트랜잭션을 commit한다.
서버와 클라이언트에서 사용하는 함수로 트랜잭션을 rollback한다.
서버와 클라이언트에서 transaction_timeout 설정 함수로 transaction_timeout 특성을 타임아웃 값으로 설정한다.
서버와 클라이언트에서 transaction_control 특성을 컨트롤값으로 설정한다.
서버와 클라이언트에서 commit_return 특성을 설정하는 함수로 when_return값으로 반환한다.
서버와 클라이언트에서 전역 트랜잭션 정보를 반환한다.
-
RQ 시스템
함수 설명 서버와 클라이언트에서 RQ에 데이터를 저장한다.
서버와 클라이언트에서 RQ로부터 데이터를 로드한다.
서버와 클라이언트에서 사용되는 함수로 RQ에 저장된 데이터의 통계를 요청한다.
서버와 클라이언트에서 tpdeq로 RQ에서 데이터를 읽은 경우 해당 데이터의 서비스명을 알려고 할 때 사용한다.
-
이벤트를 활용하는 API
함수 설명 서버와 클라이언트에서 사용되는 함수로 특정 사건의 메시지에 대한 요청을 등록한다.
서버와 클라이언트에서 사용하는 함수로 특정 사건의 메시지에 대한 등록을 해제한다.
서버와 클라이언트에서 특정 사건을 발생시키고 메시지를 전달한다.
-
브로드 캐스트/멀티 캐스트
함수 설명 클라이언트나 서버가 다른 클라이언트에게로 비요청 메시지를 보내는 경우 사용한다.
-
Windows 환경 프로그래밍
-
tmaxmt.dll
함수 설명 Tmax에 접속하여 서비스를 요청하고 결과를 받아 다시 원하는 Window의 프로시저로 넘긴 후 연결을 종료한다.
Tmax에 접속하여 서비스를 요청하고 응답은 지정한 Callback 함수로 받는다.
-
WinTmax.dll
함수 설명 메시지를 처리하는 스레드를 생성하고 사용 메모리를 초기화한다.
메시지를 처리하는 스레드를 종료하고 사용 메모리를 해제한다.
Tmax에 도착한 데이터를 보낼 Windows와 메시지 번호를 지정한다.
클라이언트에서 서비스를 호출하고 즉시 다른 일을 할 수 있도록 한다.
-
-
MultiThread/MultiContext API
함수 설명 현재 컨텍스트를 반환한다.
현재 컨텍스트를 설정한다.
2. 연결 및 해제
Tmax와 연결 및 해제하는 데 사용하는 함수에 대한 설명이다.
2.1. tpstart
클라이언트를 Tmax 시스템에 연결하는 함수로 서비스 요청이나 트랜잭션 처리 등의 ATMI 함수들을 사용하기 전에 tpstart()를 이용하여 클라이언트를 Tmax 시스템에 연결해야 한다.
tpstart()를 호출하기 전에 다른 ATMI 함수들(tpalloc()이나 tpcall() 등)이 먼저 호출되면 내부적으로 tpstart(NULL) 함수가 호출된다. 이와 같은 동작을 원하지 않을 경우에는 환경변수 TMAX_ACTIVATE_AUTO_TPSTART를 N으로 지정 할 수 있으며, 다른 ATMI 함수를 호출할 때 내부적으로 tpstart(NULL)을 호출하지 않고 TPEPROTO 에러가 발생한다. tpstart()가 성공적으로 반환되면 클라이언트는 최초 서비스 요청이나 트랜잭션 정의 등을 할 수 있다. 성공적으로 Tmax 시스템에 연결이 된 후에 다시 tpstart()가 호출되면 TPEPROTO 에러가 발생한다. tpstart()를 사용하여 Tmax 시스템과 연결하기 위해서는 Tmax 시스템이 설치된 서버의 IP와 포트 번호를 알아야한다.
다음은 서버의 정보를 알기 위한 환경변수에 대한 설명이다.
변수명 | 설명 |
---|---|
TMAX_HOST_ADDR |
클라이언트가 연결될 노드의 IP 주소로 클라이언트가 tpstart()를 호출할 경우에 내부적으로 서버 시스템에 연결되는 데 사용된다. |
TMAX_HOST_PORT |
클라이언트가 연결될 노드의 포트 번호를 지정한다. 클라이언트가 tpstart()를 호출할 때 내부적으로 서버 시스템과의 연결을 위해 TMAX_HOST_ADDR과 함께 사용된다. Tmax 환경 파일에 TPORTNO로 정의된 값이어야 한다. 클라이언트와 서버가 같은 노드에 존재하는 경우 TCP/IP소켓을 이용하지 않고 도메인 소켓을 이용하여 더 효과적인 처리를 할 수 있다. 이 경우에는 Tmax 환경 파일에 TPORTNO로 정의된 값 대신에 PATHDIR을 지정하면 된다. Tmax 환경 파일의 DOMAIN 절과 NODE 절의 TPORTNO 항목을 참고한다. |
TMAX_BACKUP_ADDR |
TMAX_HOST_ADDR 주소의 노드에 장애가 생겼을 경우에 대비하여 또 다른 Tmax 시스템 노드를 지정한다. 클라이언트는 TMAX_HOST_ADDR 주소의 노드로 연결을 시도하고, 그 노드와의 연결에 실패하면 TMAX_BACKUP_ADDR 주소의 노드로 접속을 시도한다. |
TMAX_BACKUP_PORT |
TMAX_BACKUP_ADDR 주소의 노드에 대한 Tmax 시스템 포트 번호이다. |
TMAX_CONNECT_TIMEOUT |
Tmax 시스템에 연결될 때의 타임아웃 시간으로 micro-seconds resolution이 제공된다(예: 3.5). |
-
프로토타입
#include <atmi.h> int tpstart (TPSTART_T *tpinfo )
-
파라미터
tpinfo는 TPSTART_T 라는 구조체에 대한 포인터(pointer)로 TPSTART라는 버퍼 타입을 사용하며, tpstart()를 호출하기 전에 반드시 tpalloc()에 의해 할당되어야 한다. 할당된 버퍼는 tpstart() 호출 후에 tpfree()를 통해 제거되어야 한다. 클라이언트는 시스템 연결할 때에 구조체 형식인 tpinfo 파라미터를 통해 필요한 정보를 넘긴다. tpinfo 파라미터는 클라이언트 정보, 비요청 메시지 처리 여부, 보안 정보 등을 포함한다.
tpinfo는 NULL 값을 사용할 수 있다. NULL인 경우 cltid, dompwd, usrname, usrpwd는 길이가 0인 string이 주어지고 Tmax 보안 특징을 사용하지 않으며 flags는 선택되지 않는다.
다음은 TPSTART_T 구조체의 구성이다.
struct TPSTART_T{ char cltid[MAXTIDENT+2]; /*클라이언트명 (tpbroadcast())*/ char dompwd[MAX_PASSWD_LENGTH+2]; /*시스템 접속 보안에 대한 암호*/ char usrname[MAXTIDENT+2]; /*사용자 인증 보안에 대한 계정*/ char usrpwd[MAX_PASSWD_LENGTH+2]; /*사용자 인증 보안에 대한 암호*/ int flags; /*비요청 메시지 유형과 시스템 접근 방법결정*/ } ;
멤버 설명 cltid
최대 길이 30자까지 가능한 NULL로 끝나는 문자열로 애플리케이션에서 정의한 이름이다. tpbroadcast()에서 비요청 메시지를 보낼 클라이언트를 지정할 때 사용된다.
dompwd
Tmax에서 제공하는 보안 단계 중 시스템 접속 제어를 위해 사용된다. Tmax 환경 파일 중 DOMAIN 절의 OWNER 항목에 설정된 계정에 대한 암호를 등록한다.
usrname
Tmax에서 제공하는 보안 단계 중 사용자 인증을 위해 사용된다. usrname은 Tmax 시스템의 passwd 파일에 등록된 계정 이름이다.
usrpwd
usrname에 해당하는 암호이다. 사용자 인증 보안이 설정된 경우 클라이언트는 usrname과 usrpwd를 등록해야만 Tmax 시스템에 연결되고 시스템에서 제공하는 서비스를 받을 수 있다. 보안 설정에 대한 내용은 source config 파일의 DOMAIN 절에 있는 SECURITY 항목을 참고한다.
flags
비요청(notification) 메시지 처리와 시스템 접근 방법을 결정하기 위해 사용된다. 비요청 메시지 처리를 위해 사용할 수 있는 flags이다.
-
TPUNSOL_POLL : 비요청 메시지를 수신한다.
-
TPUNSOL_HND : 비요청 메시지를 수신할 함수를 지정한다. 자세한 내용은 tpsetunsol을 참고한다.
-
TPUNSOL_IGN : 비요청 메시지를 무시한다. 기본값이 정의되지 않으면 TPUNSOL_IGN이 설정된다.
-
-
반환값
반환값 설명 0 또는 1
함수 호출에 성공한 경우이다. primary host에 0을 반환하고 backup host에 1을 반환한다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpstart()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 tpinfo가 NULL이나 TPSTART_T 구조체에 대한 포인터가 아닌 경우에 발생한다.
[TPEITYPE]
tpinfo가 TPSTART_T 구조체에 대한 포인터가 아니다.
[TPEPROTO]
tpstart()가 부적절한 곳에서 호출되었다. 예를 들어 서버 프로그램에서 사용되었거나 이미 연결된 상황에서 재호출된 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하거나 환경변수 설정이 잘못된 경우이다. 예를 들어 TMAX_HOST_ADDR나 TMAX_HOST_PORT가 잘못 설정되어 연결이 실패한 경우에 발생한다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { int ret; char *buf; long len; TPSTART_T *tpinfo; tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T)); if (tpinfo==NULL) { error processing } strcpy(tpinfo->cltname, “cli1”); strcpy(tpinfo->usrname, “navis”); strcpy(tpinfo->dompwd, “tmax”); tpinfo->flags = TPUNSOL_HND; ret=tpstart(tpinfo); if (ret==-1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; ret=tpcall(“SERVICE”, buf, 20, &buf, &len, TPNOFLAGS); if (ret==-1) { error processing } data process.... tpfree((char *) buf); tpend(); }
-
관련 함수
tpend()
2.2. tpend
클라이언트에서 Tmax 시스템과의 연결을 해제하는 함수로 클라이언트가 트랜잭션 모드에 있다면 트랜잭션은 자동으로 rollback된다. tpend()가 성공적으로 반환하면 호출자는 더 이상 어떤 프로그램과도 통신할 수 없고, 어떤 트랜잭션에도 참여할 수 없다. 또한 유지되고 있는 대화형 연결은 즉시 종료된다.
tpend()가 한 번 이상 호출된다면(이미 Tmax 시스템과 연결이 해제된 후에 또 다시 호출된다면) -1 값을 반환하지만 시스템에는 아무런 작동도 하지 않는다.
-
프로토타입
# include <atmi.h> int tpend (void)
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpend()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEPROTO]
tpend()가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 서버인 경우나 또는 연결이 해제된 후에 다시 호출된 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { char *sndbuf, *rcvbuf; long rcvlen, sndlen; int ret; ret=tpstart((TPSTART_T *)NULL) if (ret==-1) {error processing } buf = (char *)tpalloc(“STRING”, NULL, 0) if (buf=NULL) { error processing } data process … ret=tpcall(“SERVICE”, buf, 0, &buf, &len, TPNOFLAGS); if (ret==-1) { error processing } data process … printf(“ data: %s\n”, buf); tpfree((char *)buf); tpend(); }
-
관련 함수
tpstart()
3. 동기형 통신
동기형 통신을 할 때 사용하는 함수에 대해 설명한다.
3.1. tpcall
서버와 클라이언트의 동기형 서비스 요청 송수신 함수로 동기형 통신으로 svc로 명명된 서비스에게 서비스 요청을 송신하고 이에 대한 응답을 수신한다. tpacall() 호출 후 연속적으로 tpgetrply()를 호출하는 것과 동일하게 처리된다.
tx_begin 호출 이후 tx_time이 지난 이후에 tpacall은 TPNOTRAN | TPNOREPLY를 flag에 설정한 호출만 성공하며 나머지는 모두 TPETIME 에러를 발생시킨다.
-
프로토타입
# include <atmi.h> int tpcall (char *svc, char *idata, long ilen, char **odata, long *olen, long flags)
-
파라미터
파라미터 설명 svc
호출되는 서비스명으로 Tmax 응용 서버 프로그램에서 제공되고 있는 것이어야 한다.
idata
서비스 요청의 데이터에 대한 포인터이다. 반드시 이전에 tpalloc()에 의해 할당된 버퍼이어야 한다. idata의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다.
ilen
송신할 데이터의 길이이다.
-
idata가 가리키는 버퍼가 특별한 길이 명시가 필요없는 버퍼 유형(STRING, STRUCT, X_COMMON, X_C_TYPE)인 경우 ilen은 무시되고 기본으로 0을 사용한다.
-
idata가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET, CARRAY, MULTI STRUCTURE)인 경우 ilen은 0이 될 수 없다.
-
idata가 NULL인 경우 ilen은 무시된다.
*odata
*odata는 수신될 응답 버퍼에 대한 포인터로 버퍼는 *olen으로 반환된 길이 만큼의 응답이 수신된다. *odata는 반드시 이전에 tpalloc()에 의해 할당된 버퍼이어야 한다.
동일한 버퍼가 송신과 수신 역할을 모두 한다면, *odata는 idata의 주소로 설정되어야 한다. 응답 버퍼의 크기 변경 여부를 결정하기 위해서 tpcall()의 완료 전에 *odata로 할당된 응답 버퍼의 크기와 수신된 *olen을 비교한다. 수신된 *olen이 더 크다면 할당된 응답 버퍼의 크기가 증가되며, 그렇지 않으면 크기는 변경되지 않는다.
idata와 *odata로 동일한 버퍼가 사용되어 tpcall()이 호출된 경우 *odata가 변경되었다면 idata가 가리키는 주소는 더 이상 유효하지 않다. *odata는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다.
*olen이 0으로 반환되었다면, 어떤 데이터도 수신되지 않고 *odata와 *odata가 가리키는 버퍼 모두 아무런 변화가 없다. *odata나 olen이 NULL이 되는 것은 에러이다.
*olen
*odata에 반환될 응답에 대한 길이이다.
flags
호출할 때 사용되는 옵션으로 어떤 방식으로 통신할 것인지를 지정한다.
flags로 사용 가능한 값은 다음과 같다.
-
TPNOTRAN
tpcall() 호출자가 트랜잭션 모드 상태에서 이 flags를 설정하여 svc 서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된다. 트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpcall()이 트랜잭션 모드에서 호출되는 경우 flags는 반드시 TPNOTRAN으로 설정해야 한다. 트랜잭션 모드 내에서 tpcall()를 호출할 때 TPNOTRAN으로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다. 즉, 트랜잭션 타임아웃이 지난 이후의 TPNOTRAN을 적용한 tpcall도 호출하지 않고 실패를 한다는 의미이다. TPNOTRAN으로 호출된 서비스가 실패하였을 경우 호출자의 트랜잭션에는 영향을 미치지 않는다.
-
TPNOCHANGE
TPNOBLOCK flags를 설정한 상태에서 내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패한다. TPNOCHANGE은 tpcall()의 Tx 부분에만 적용된다. TPNOBLOCK flags 설정 없이 tpcall()을 호출할 때 블로킹 상황이 발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아웃 또는 블록 타임아웃)이 발생할 때까지 대기한다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기다리겠다는 것을 의미한다. 트랜잭션 타임아웃 내에서 tpcall()을 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용한다. 내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 TPSIGRSTRT flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpcall()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않거나 flags가 유효하지 않다. 예를 들어 svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가리킨다.
[TPENOENT]
svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.
[TPEITYPE]
data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다.
[TPEOTYPE]
수신된 응답 버퍼의 유형이나 하위 유형이 호출자가 알지 못하는 유형이다.
flags가 TPNOCHANGE로 설정되었는데 *odata가 가리키는 버퍼의 유형 및 하위 유형이 수신된 응답 버퍼의 유형 및 하위 유형과 맞지 않은 경우 *odata의 내용과 *olen은 모두 변경되지 않는다. 호출자가 트랜잭션 모드에서 서비스를 요청하였다면, 그 트랜잭션은 응답이 무시되었기 때문에 rollback된다.
[TPETRAN]
트랜잭션 서비스를 호출할 때 데이터 베이스에 문제가 발생하여 xa_start가 실패하였다.
[TPETIME]
타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면 트랜잭션 타임아웃이 발생하였고 그 트랜잭션은 rollback된다.
트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면, 블록 타임아웃이 발생한다. 이 두 경우에 *odata의 내용과 *olen은 변경되지 않는다.
트랜잭션 타임아웃이 발생하였다면 새로운 서비스 요청을 송신한다거나 응답을 대기하는 일은 트랜잭션이 rollback될 때까지 [TPETIME] 에러로 실패하게 된다.
[TPESVCFAIL]
서비스 요청에 대한 응답을 송신하는 서비스 루틴이 애플리케이션에서 에러가 발생하여 TPFAIL로 tpreturn()을 호출하였다. 서비스 응답이 수신되었다면 그 내용들은 *odata가 가리키는 버퍼를 통하여 사용될 수 있다.
트랜잭션 타임아웃이 발생해서 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 통신이 정상적으로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션을 완료할 때에 모두 rollback된다.
[TPESVCERR]
서비스 루틴 수행 중이나 tpreturn()(예를 들어 잘못된 파라미터가 전달된 경우) 수행 중에 에러가 발생하였다. 에러가 발생하면 어떠한 응답 데이터도 반환되지 않고 *odata의 내용 또는 *olen 모두 변경되지 않는다.
tpalloc로 생성되지 않은 버퍼를 사용하였거나 할당된 버퍼의 Tmax 헤더가 잘못된 포인터(memcpy 등)의 영향을 받았거나, tpacall이나 tpconnect의 cd로 반환하였을 경우 Recv 모드에서 서비스가 유효하지 않은 대화형 내용일 경우에 발생한다. 단, tpreturn을 시도하면 클라이언트는 TPESVCERR를 받는다.
클라이언트가 강제로 대화를 해제하여 서비스 프로그램이 TPEV_DISCOMN을 받는 것과 같은 TPEV_DISCOMN 이벤트가 발생하였을 경우 클라이언트는 서비스의 tpreturn에 TPESVCERR tperrno를 전송받는다.
함수 호출자가 트랜잭션 모드에 있을 경우 트랜잭션 타임아웃이 발생하기 전까지는 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 이들이 제대로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션이 완료되면 모두 rollback된다.
Tmax 환경 파일에 서비스별로 SVCTIMEOUT을 설정할 수 있는데 서비스의 수행시간이 이 시간을 초과하게 되면 서비스는 수행을 멈추고 TPESVCERR를 반환한다. SVCTIMEOUT이 발생하면 tpsvctimeout()을 불러주는데 이 함수 내에서 버퍼 해제, 로깅 작업 등 업무별로 적당한 작업을 할 수 있다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpcall()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { int ret; char *sndbuf, *rcvbuf; long sndlen, rcvlen; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } sndbuf = (char *)tpalloc(“CARRAY”, NULL, 20); if (sndbuf==NULL) {error processing }; rcvbuf = (char *)tpalloc(“CARRAY”, NULL, 20); if (rcvbuf==NULL) {error processing }; data process.... sndbuf=strlen(sndbuf); ret=tpcall(”SERVICE”, sndbuf, sndlen, &rcvbuf, &rcvlen, TPNOCHANGE); if (ret==-1) { error processing } data process.... tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); }
-
관련 함수
tpalloc(), tpacall(), tpgetrply(), tpreturn()
4. 비동기형 통신
비동기형 통신에서 사용하는 함수에 대해 설명한다.
4.1. tpacall
서버와 클라이언트에서 비동기 서비스 요청을 송신하는 함수로 svc로 명명된 서비스에게 서비스 요청 메시지를 송신한다. 비동기 통신으로 메시지를 송신한 후에 결과를 받을 때까지 기다리지 않고 바로 반환된다. 결과는 tpgetrply()를 이용하여 응답을 받을 수도 있고, 또는 tpcancel()를 이용하여 응답을 취소할 수 있다.
tx_begin 호출 이후 tx_time이 지난 이후에 tpacall은 TPNOTRAN | TPNOREPLY를 flag에 설정한 호출만 성공하며 나머지는 모두 TPETIME 에러를 발생시킨다.
tpacall이 성공한 경우 반환값 범위의 제한은 int 값 범위 중 양의 정수 부분인 1부터 2147438647이다.
-
프로토타입
# include <atmi.h> int tpacall (char *svc, char *data, long len, long flags)
-
파라미터
파라미터 설명 svc
호출되는 서비스명으로 Tmax 응용 서버 프로그램에서 제공되는 것이어야 한다.
data
NULL 값이 아닌 경우 반드시 tpalloc()으로 할당된 버퍼에 대한 포인터이어야 한다.
len
송신되는 데이터 길이이다.
-
data가 가리키는 버퍼가 특별한 길이 명시가 필요없는 버퍼 유형(STRING, STRUCT, X_COMMON, X_C_TYPE)이라면 len은 무시되고 보통 0이 사용된다.
-
data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형(X_OCTET, CARRAY, MULTI STRUCTURE)이라면 len은 0이 될 수 없다.
-
data가 NULL이라면 len은 무시되고 데이터 없이 서비스 요청이 송신된다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다. 서비스 요청이 트랜잭션 모드에서 송신되었다면 해당 응답은 반드시 수신되어야 한다.
flags
호출할 때 사용되는 옵션으로 호출 모드를 결정한다. flags로 사용 가능한 값은 다음과 같다.
-
TPBLOCK
flags 없이 tpacall()이 사용되었다면, svc에 호출된 서비스가 없거나 잘못된 결과가 반환되었어도 정상적인 결과가 반환된다. tpgetrply()를 호출할 때 에러가 반환된다. TPBLOCK을 이용해 tpacall()을 호출할 경우 서비스 상태의 정상 여부를 확인할 수 있다. -
TPNOTRAN
트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpacall()이 트랜잭션 모드에서 호출되는 경우 flags는 반드시 TPNOTRAN으로 설정해야 한다. tpacall() 호출자가 트랜잭션 모드 상태에서 TPNOTRAN을 설정하여 svc 서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된다. 트랜잭션 모드 내에서의 tpacall()을 호출할 때 TPNOTRAN로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다. 즉, 트랜잭션 타임아웃이 지난 이후의 TPNOTRAN을 적용한 tpcall도 호출하지 않고 실패를 한다는 의미이다. 예외적으로 TPNOTRAN|TPNOREPLY를 적용한 tpacall은 호출을 허용한다. TPNOTRAN으로 호출된 서비스가 실패하였을 경우 호출자의 트랜잭션에는 영향을 미치지 않는다. -
TPNOREPLY
tpacall()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한다. 결과는 나중에 tpacall()에서 반환한 구별자를 이용하여 tpgetrply()의 결과를 수신한다. flags를 TPNOREPLY로 설정하면 서비스에 대한 응답을 받지 않는다고 설정된다. TPNOREPLY로 설정하면 tpacall()은 서비스가 정상적으로 호출되면 0을 반환한다. 함수 호출자가 트랜잭션 모드에 있을 경우에는 반드시 TPNOTRAN과 함께 설정해야만 TPNOREPLY를 사용할 수 있다. TPNOREPLY인 경우 서비스 상태의 정상 여부를 체크하기 위해서는 TPBLOCK을 함께 설정해야 한다. TPBLOCK을 설정하지 않으면 서비스가 NRDY인 경우에도 에러를 반환하지 않는다. -
TPNOBLOCK
내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패하도록 설정하는 flags이다. TPNOBLOCK flags 설정 없이 tpacall()이 호출된 경우 블로킹 상황이 발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아웃 또는 블록 타임아웃)이 발생할 때까지 대기한다. -
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기하도록 설정하는 flags이다. 트랜잭션 타임아웃 내에서 tpacall()을 수행한 경우에는 여전히 트랜잭션 타임아웃이 적용된다. -
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용하는 flags로 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT flag와 TPBLOCK flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT가 설정되지 않은 상태에서 시그널 인터럽트가 발생했다면 함수는 실패 처리되고 tperrno에 TPGOTSIG가 설정된다. -
TPNOCALLBACK
UCS의 usrmain()에서 tpacall()을 호출할 때 tpregcb()를 이용하여 콜백함수를 등록할 수 있다. flags를 TPNOCALLBACK로 설정하면 콜백함수에서 응답 처리하지 않고 tpgetrply()에서 응답을 처리한다.
-
-
반환값
반환값 설명 구별자(descriptor)
함수 호출에 성공한 경우이다. 반환된 구별자는 송신된 서비스 요청에 대한 응답을 수신하는 데 사용된다.
-1
함수 호출이 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpacall()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않은 경우 발생한다. 예를 들어 svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는 flags가 유효하지 않은 경우에 발생한다.
[TPENOENT]
svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.
[TPEITYPE]
data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우 사용된 구조체가 SDLFILE 파일에 선언되어 있지 않은 경우 발생한다.
[TPELIMIT]
처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에 호출자의 서비스 요청이 송신되지 않은 경우 발생한다.
[TPETIME]
타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드인 경우 트랜잭션 타임아웃이 발생한 것이며 트랜잭션은 rollback된다. 함수 호출자가 트랜잭션 모드가 아닌 경우 TPNOTIME이나 TPNOBLOCK이 모두 설정되지 않은 상황에서 블록 타임아웃이 발생한다. 트랜잭션 타임아웃이 발생하는 경우 트랜잭션이 rollback될 때까지 새로운 서비스 요청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두 [TPETIME] 에러로 실패 처리된다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
트랜잭션 모드에서의 TPNOREPLY 서비스 호출할 때 TPNOTRAN flags를 설정하지 않는 경우 등 부적절한 상황에서 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { char *buf; int ret,cd; long len; ret=tpstart((TPSTART_T *)NULL); if (ret<0) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing } data process.... cd = tpacall(“SERVICE”, sndbuf, 20, TPNOTIME); if (cd<0) {error processing } data process… ret=tpgetrply(&cd, (char **)&buf, &len, TPNOTIME); if (ret<0) { error processing } data process.... tpfree((char *)buf); tpend(); }
-
관련함수
tpalloc(), tpcall(), tpcancel(), tpgetrply()
4.2. tpgetrply
서버와 클라이언트에서 비동기적으로 요청한 서비스에 대한 응답을 수신하는 함수로 tpacall()로 요청한 서비스에 대한 응답을 수신한다.
-
프로토타입
# include <atmi.h> int tpgetrply(int *cd, char **data, long *len, long flags)
-
파라미터
파라미터 설명 cd
tpacall()에 의해 반환된 호출 구별자를 가리킨다. 보통 cd와 일치하는 응답이 수신되거나 또는 타임아웃이 발생할 때까지 기다린다. 일반적으로 cd는 응답이 수신된 후에는 더 이상 유효하지 않다.
*data
반드시 이전에 tpalloc()에 의해 할당된 버퍼에 대한 포인터이어야 한다.
len
tpgetrply()가 성공적으로 수신한 데이터의 길이로 필요한 경우 응답 내용이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다.
*data는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다. len이 호출 전 버퍼의 총 크기보다 크다면, len이 그 버퍼의 새로운 크기가 된다. len이 0으로 반환되는 경우 어떤 응답도 수신되지 않고 *data와 len이 지시하는 버퍼 모두 아무런 변화가 없다.
*data나 len이 NULL이 되는 것은 에러이다.
flags
flags로 사용 가능한 값은 다음과 같다.
-
TPGETANY
입력값으로 설정한 cd를 무시하고, 이에 상관없이 수신 가능한 응답을 반환하도록 한다. cd는 반환된 응답에 대한 호출 구별자가 된다. 아무런 응답이 없으면 일반적으로 tpgetrply()는 응답이 도착할 때까지 대기한다. TPGETANY가 설정되지 않은 경우 특별한 언급이 없는 한 *cd는 무효화됨에 유의해야 한다. TPGETANY가 설정되었다면, cd는 에러가 발생한 응답에 대한 구별자가 된다. 응답이 반환되기 전에 에러가 발생했다면, cd는 0이 된다. 특별한 언급이 없다면, 호출자의 트랜잭션에 영향을 미치지 않는다.
-
TPNOCHANGE
*data가 가리키는 버퍼의 유형은 변경되지 못한다. 수신된 응답 버퍼와 *data가 가리키는 버퍼의 유형이 다른 경우 *data의 버퍼 유형은 수신자가 인식할 수 있는 한도 내에서 수신된 응답 버퍼의 유형으로 변경되는데 TPNOCHANGE flags가 설정되는 경우에는 변경되지 않는다 . 수신된 응답 버퍼의 유형 및 하위 유형은 *data가 가리키는 버퍼의 유형 및 하위 유형과 반드시 일치해야 한다.
-
TPNOBLOCK
응답이 도착할 때까지 대기하지 않는다. 수신 가능한 응답이 있는 경우에는 반환을 한다. TPNOBLOCK flags가 지정되지 않았고 수신 가능한 응답이 없다면 함수 호출자는 응답이 도착하거나 또는 타임아웃(트랜잭션 타임아웃이나 블록 타임아웃)이 발생할 때까지 대기한다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기한다. 트랜잭션 모드에서 tpgetrply()를 한 경우에는 트랜잭션 타임아웃이 적용된다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용한다. 내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 TPSIGRSTRT flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다. tpreturn()으로 전달되는 tpurcode 전역변수는 tpgetrply()가 성공적으로 반환되었거나 tperrno가 [TPESVCFAIL]인 경우 애플리케이션에서 정의한 값을 갖게 된다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpgetrply()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 cd나 data, *data, len 등이 NULL이거나 또는 flags가 유효하지 않은 경우에 발생한다. cd가 NULL이 아니면 에러 발생 후에도 cd는 유효하며, 그에 대한 응답을 계속 기다린다.
[TPEBADDESC]
cd가 유효하지 않은 구별자이다.
[TPEOTYPE]
수신된 응답의 유형 또는 하위 유형이 호출자가 알지 못하는 유형이다.
flags가 TPNOCHANGE로 설정되었는데, *data의 유형 및 하위 유형이 서비스가 송신한 응답의 것과 맞지 않는 경우로 *data의 내용과 *len은 모두 변경되지 않는다. 응답이 호출자의 트랜잭션 모드에서 수신되었다면, 그 트랜잭션은 응답이 무시되었기 때문에 rollback된다.
[TPETIME]
타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그 트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면, 블록 타임아웃이 발생하였다. 이 두 경우에, *data의 내용과 *len은 변경되지 않는다. 트랜잭션 타임아웃이 발생했다면, 새로운 서비스 요청을 송신한다거나 응답을 기다리는 일은 트랜잭션이 rollback될 때까지 [TPETIME] 에러로 실패하게 된다.
[TPESVCFAIL]
서비스 요청에 대한 응답을 송신하는 서비스 루틴이 애플리케이션에 에러가 발생하여 TPFAIL로 tpreturn()을 호출하였다. 서비스 응답이 수신되었다면, 그 내용들은 *data가 가리키는 버퍼를 통해 사용될 수 있다. 함수 호출자가 트랜잭션 모드에 있다면, 그 트랜잭션은 rollback된다.
트랜잭션 타임아웃이 발생하기 전까지는 트랜잭션이 rollback되기 전에 다른 통신들이 시도될 수 있다. 그러한 통신들은 정상적으로 처리될 수도 있고, 또는 실패할 수도 있다. 이들이 제대로 수행되기 위해서는 TPNOTRAN이 설정되어야 한다. 호출자의 트랜잭션 모드에서 수행된 작업들은 트랜잭션이 완료되면 모두 rollback된다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하는 경우로 구별자(cd)는 유효하다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpgetrply()이 부적절한 상황에서 호출되었다.
[TPETRAN]
트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가 실패하였다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { int ret; long len; char *buf; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process … cd = tpacall(“SERVICE”, buf, 0, TPNOFLAGS); if (cd==-1) { error procesing } data process.... ret=tpgetrply(&cd, &buf, &len, TPNOTIME); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpacall(), tpalloc(), tpreturn()
4.3. tpcancel
서버와 클라이언트의 응답 취소 함수로 tpacall()이 반환한 호출 구별자인 cd를 취소한다.
-
프로토타입
# include <atmi.h> int tpcancel (int cd)
-
파라미터
파라미터 설명 cd
tpacall()이 반환한 호출 구별자로 취소 대상을 설정한다. 전역 트랜잭션(global transaction)과 관련된 서비스는 취소할 수 없다. 서비스 응답이 성공적으로 취소되면, cd는 무효화되고 cd를 통해 받은 응답들도 모두 무시된다.
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpcancel()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEBADDESC]
cd가 유효하지 않은 구별자이다.
[TPETRAN]
cd가 호출자의 전역 트랜잭션과 관련되어 있다. cd는 여전히 유효하고, 호출자의 현재 트랜잭션은 영향을 받지 않는다.
[TPEPROTO]
tpcancel()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { char *test[2]; int ret, i, cd[2]; long len; if (argc != 4) { error processing } ret=tpstart((TPSTART_T *)NULL; if (ret==-1) { error processing } for (i=0; i<3; i++) { test[i] = tpalloc(“STRING”,NULL,0); if (test[I])==NULL} { error processing } strcpy(test[i],argv[i+1]); cd[i]=tpacall(“SERVICE”, test[i], 0, TPNOTIME); ) ret=tpcancel(cd[1]); /* 2번째 응답을 취소한다. */ if (ret==-1) { error processing } for (i=0; i<3; i++) { ret=tpgetrply(&cd[i], (char **)&test[i], &len, TPNOTIME) if (ret==-1) printf(“Can’t rcv data from service of %d\n”,cd[i]); else prtinf(“%dth rcv data : %s\n”, I+1, test[I]); tpfree(test[I]); } tpend(); }
-
관련함수
tpacall()
5. 대화형 통신
대화형 통신에서 사용되는 함수에 대해 설명한다.
5.1. tpconnect
서버와 클라이언트에서 프로그램이 대화형 서비스 svc와 통신을 연결하는 함수이다. 통신은 동시에 수신 또는 송신만 가능한 반 이중(half-duplex) 형태이다. 연결을 설정하는 과정에서 함수 호출자는 서비스 루틴에게 데이터를 전달할 수 있다. 대화형 서비스는 TPSVCINFO 구조체를 통하여 data와 len을 수신하기 때문에 tpconnect()로 전달된 데이터들을 수신하기 위하여 tprecv()를 호출할 필요가 없다.
-
프로토타입
# include <atmi.h> int tpconnect (char *svc, char *data, long len, long flags)
-
파라미터
파라미터 설명 svc
대화형 서비스의 서비스 이름을 지정한다.
data
호출자가 데이터를 전달하려는 경우 반드시 tpalloc()에 의해 이전에 할당된 버퍼이어야 한다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다.
len
전달할 데이터 길이를 지정한다.
-
data가 가리키는 버퍼가 특별한 길이 명시가 필요없는 버퍼 유형(STRING, STRUCT, X_COMMON, X_C_TYPE)이라면, len은 무시되고 보통 0이 사용된다.
-
data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형( X_OCTET, CARRAY, MULTI STRUCTURE)이라면, len은 0이 될 수 없다.
-
data가 NULL이라면, len은 무시되고, 이 경우 아무런 데이터도 대화형 서비스에게 넘겨지지 않는다.
flags
flags로 사용 가능한 값은 다음과 같다.
-
TPNOTRAN
tpconnect() 호출자가 트랜잭션 모드 상태에서 이 flags를 설정하여 svc 서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된다. 트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면, tpconnect()가 트랜잭션 모드에서 호출되는 경우 flags는 반드시 TPNOTRAN으로 설정해야 한다. 트랜잭션 모드 내에서의 tpconnect()를 호출할 때, TPNOTRAN으로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다. TPNOTRAN으로 호출된 서비스가 실패하였을 경우 호출자의 트랜잭션에는 영향을 미치지 않는다.
-
TPSENDONLY
연결이 완료된 후 함수 호출자는 처음 데이터를 송신만 할 수 있고 요청된 서비스만 할 수 있도록 설정하는 flags이다. 호출자가 처음 통신 제어권을 가진다. TPSENDONLY나 TPRECVONLY 중 하나는 반드시 지정되어야 한다.
-
TPRECVONLY
연결이 완료된 후 함수 호출자는 데이터를 수신할 수만 있고 요청된 서비스가 처음 데이터를 송신을 시작하도록 하는 flags이다. 즉, 요청된 서비스가 처음 통신 제어권을 가진다. TPSENDONLY나 TPRECVONLY 중 하나는 반드시 지정되어야 한다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기하겠다는 것을 의미한다. 트랜잭션 타임아웃 내에서 tpconnect()를 수행한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용한다. 내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 TPSIGRSTRT flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
-
반환값
반환값 설명 구별자(descriptor)
함수 호출에 성공한 경우이다. 차후 연결을 위하여 참조될 구별자(descriptor)를 반환한다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpconnect()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다. 특별한 언급이 없다면 함수 호출을 실패할 경우 호출자의 트랜잭션에 영향을 미치지 않는다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다.
예를 들어 svc와 data가 NULL인 경우 지시하는 버퍼가 tpalloc()으로 할당되지 않았거나, flags가 TPSENDONLY 또는 TPRECVONLY로 지정되지 않은 경우 또는 flags가 유효하지 않은 경우에 발생한다.
[TPENOENT]
svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.
[TPEITYPE]
data의 유형 및 하위 유형이 svc가 지원할 수 있는 유형 및 하위 유형이 아니다.
[TPELIMIT]
연결 개수가 최대 한계에 도달했기 때문에 서비스를 요청할 수 없다.
[TPETRAN]
트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가 실패하였다.
[TPETIME]
타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하고 그 트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면, 블록 타임아웃이 발생하였다. 트랜잭션 타임아웃이 발생하였다면 새로운 서비스 요청은 트랜잭션이 rollback될 때까지 [TPETIME] 에러로 실패한다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpconnect()가 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { char *buf; int ret, cd; long len, revent; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=tpalloc(“STRING”,NULL,0); if (buf=NULL) { error procesing } data process .... cd = tpconnect(“SERVICE”,sndbuf,0,TPRECVONLY); if (cd==-1) { error processing } data process.... ret=tprecv(cd, &buf, &len, TPNOFLAGS, revent); if (ret==-1) { error processing } tpfree(buf); tpend(); }
-
관련함수
tpalloc(), tpdiscon(), tprecv(), tpsend()
5.2. tpsend
서버와 클라이언트에서 사용하는 함수로 대화형 통신에서 상대방 프로그램에게 데이터를 송신한다. 호출자는 반드시 통신 제어권을 가지고 있어야 한다.
-
프로토타입
# include <atmi.h> int tpsend (int cd, char *data, long len, long flags, long *revent)
-
파라미터
파라미터 설명 cd
데이터가 송신되는 연결을 지정하는 것으로 tpconnect()나 TPSVCINFO 매개변수로부터 반환되는 구별자이다.
data
tpalloc()에 의해 할당된 버퍼이다. 애플리케이션 데이터가 아무 것도 송신되지 않을 경우(예를 들어 어떤 데이터도 전달하지 않고 통신 제어권만을 넘기는 경우)에는 data는 NULL이 될 수 있다. data의 유형 및 하위 유형은 연결된 상대방이 인식할 수 있는 유형 및 하위 유형이어야 한다.
len
송신하는 버퍼의 길이로 data가 길이 명시가 필요없는 버퍼를 가리키면 len은 무시되고 보통 0이 사용된다. data가 길이 명시가 반드시 필요한 버퍼를 가리킨다면 len은 0이 될 수 없다.
flags
flags로 사용 가능한 값은 다음과 같다.
-
TPNOBLOCK
내부 버퍼가 전달될 메시지들로 꽉 찬 경우와 같은 블로킹 상황이 발생하면 데이터와 이벤트들은 송신되지 않는다. TPNOBLOCK flags 설정 없이 tpsend()를 호출할 때, 블로킹 상황이 발생하면 호출자는 타임아웃(트랜잭션 또는 블록 타임아웃 중 하나)이 발생하거나 상황이 완화될 때까지 기다린다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기하는 것을 의미한다. 트랜잭션 타임아웃 내에서 tpsend()를 사용한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
-
TPRECVONLY
호출자가 데이터를 송신한 후 통신 제어권을 상대방에게 넘긴다는 의미이다. 호출자는 다시 통신 제어권을 넘겨 받기 전까지 tpsend()를 호출할 수 없다. 대화 상대방 수신자는 tprecv()로 데이터를 수신하면서 통신 제어권을 갖게 됨을 의미하는 TPEV_SENDONLY 이벤트를 수신하게 된다. 수신자 또한 다시 통신 제어권을 상대방에게 넘기기 전까지 tprecv()를 호출할 수 없다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용한다. 내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 TPSIGRSTRT flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
revent
구별자인 cd에 대한 이벤트가 존재한다면 tpsend()는 실패 처리되고 데이터는 송신되지 않는다. 이벤트 유형은 revent로 반환된다.
revent에 전달되는 이벤트들은 다음과 같다.
-
TPEV_DISCONIMM
대화 종속자에게 수신되는 이 이벤트는 대화 시작자가 tpdiscon()을 사용하여 연결을 강제로 종료하였다는 것을 의미한다. 또한 이 이벤트는 통신 에러(예를 들어 서버, 노드, 네트워크 장애 등)로 인하여 연결이 끊어졌을 때에도 반환된다.
-
TREV_SVCERR
대화 시작자에게 수신되는 이 이벤트는 아래의 TPEV_SVCFAIL 상황 이외의 경우에 대화 종속자가 통신 제어권 없이 tpreturn()을 수행하였음을 알린다.
-
TREV_SVCFAIL
대화 시작자에게 수신되는 이 이벤트는 대화 종속자가 통신 제어권 없이 tpreturn()을 수행하였으며, 이때 tpreturn()은 아무 데이터 없이 TPFAIL로 호출되었다. rval은 TPFAIL이며 data는 NULL로 수행되었음을 알린다.
-
-
반환값
반환할 경우 revent가 TREV_SVCFAIL이면, tpurcode 전역변수는 tpreturn()를 호출할 때에 전달된 rcode 값이 된다 .
반환값 설명 0
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpsend()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 data가 가리키는 버퍼가 tpalloc()으로 할당되지 않았거나 또는 flags가 유효하지 않은 경우에 발생한다.
[TPEBADDESC]
구별자(cd)가 유효하지 않다.
[TPETIME]
타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면 트랜잭션 타임아웃이 발생하고 그 트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면 블록 타임아웃이 발생한다.
이 두 경우에 *data의 내용과 len은 변경되지 않는다. 트랜잭션 타임아웃이 발생하였다면 트랜잭션이 rollback될 때까지 대화형 통신으로 메시지를 송신하거나 수신하는 일 또는 새로운 연결을 시작하는 일은 모두 [TPETIME] 에러로 실패하게 된다.
[TPEEVENT]
이벤트가 발생한 경우로 에러가 발생하면 data는 송신되지 않고, 이벤트 유형은 revent로 반환된다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpsend()가 부적절한 상황에서 호출되었다. 예를 들어 수신자 모드에서 사용하는 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include “../sdl/demo.s” main(int argc,char* argv[]) { int ret, cd; struct dat *buf; long revent, len; if (argc!=3) {error processing } ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=(struct dat *)tpalloc(“STRUCT”, “dat”, 0); if (buf==NULL) { error processing } strcpy(buf->sdata, argv[1]); data process…. cd=tpconnect(“SERVICE”, buf, 0, TPSENDONLY); if (cd==-1) { error processing } strcpy(buf->sdata, argv[2]); data process…. ret=tpsend(cd, buf, 0,TPRECVONLY,&revent); if (ret==-1) { error processing } ret=tprecv(&cd,(char**)&buf,&len,TPNOTIME,&revent); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpalloc(), tpconnect(), tpdiscon(), tprecv(), tpreturn()
5.3. tprecv
서버와 클라이언트에서 대화형 통신을 하는 경우 메시지를 수신하는 함수로 대화형 통신으로 연결된 상대방 프로그램으로부터 송신된 데이터를 수신하기 위해 사용된다. tprecv()는 클라이언트나 서버 중 통신 제어권을 갖지 않은 프로그램에서만 사용될 수 있다.
-
프로토타입
# include <atmi.h> int tprecv (int cd, char **data, long *len, long flags, long *revent)
-
파라미터
파라미터 설명 cd
데이터를 수신할 연결을 지정하는 것으로 tpconnect()나 TPSVCINFO 매개변수 중 하나로부터 반환된 구별자(descriptor)이다.
data
tpalloc()에 의해 이전에 할당된 버퍼에 대한 포인터 주소이다. 함수가 성공적으로 반환되면 *data는 수신된 데이터를 가리킨다.
len
데이터의 길이를 나타낸다.
len이 호출 전 버퍼의 총 크기보다 더 크다면 버퍼의 새로운 크기는 len이 된다.
len이 0이면 어떤 데이터도 수신되지 않았고, *data나 *data가 가리키는 버퍼 모두 아무런 변화없다. *data나 len이 NULL이면 data는 에러이다.
flags
flags로 사용 가능한 값은 다음과 같다.
-
TPNOCHANGE
수신된 응답 버퍼와 *data가 가리키는 버퍼의 유형이 다르다면 *data의 버퍼 유형은 수신자가 인식할 수 있는 한도 내에서 수신된 응답 버퍼의 유형으로 변경된다. 그러나 이 flags가 설정되었다면 *data가 가리키는 버퍼의 유형은 변경되지 못한다. 수신된 응답 버퍼의 유형 및 하위 유형은 *data가 가리키는 버퍼의 유형 및 하위 유형과 반드시 일치해야 한다.
-
TPNOBLOCK
데이터가 도착할 때까지 기다리지 않는다. 수신 가능한 데이터가 있으면 이를 반환한다. TPNOBLOCK flags가 지정되지 않고 수신 가능한 데이터가 없으면 호출자는 데이터가 도착할 때까지 대기한다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기한다는 것을 의미한다. 그러나 트랜잭션 타임아웃 내에서 tprecv()를 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용한다. 내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 TPSIGRSTRT flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
revent
다음은 revent에 반환되는 이벤트 유형에 대한 설명이다.
-
TPEV_DISCONIMM
대화 종속자에게 수신되는 이 이벤트는 대화 시작자가 tpdiscon()으로 대화형 연결을 강제로 종료했음을 의미한다. 또한 이 이벤트는 통신 에러, 예를 들어 서버, 노드, 네트워크 장애 등으로 인하여 연결이 끊어졌을 때 대화 시작자나 종속자에게 반환될 수 있다. 이것은 강제적인 연결 해제 통보이기 때문에 전달 중인 데이터는 분실될 수도 있다. 2개의 프로그램이 동일한 트랜잭션에 참여하고 있었다면 그 트랜잭션은 rollback된다. 대화형 통신에 사용되었던 구별자(cd)는 더 이상 유효하지 않다.
-
TPEV_SENDONLY
연결된 상대방 프로그램 측에서 통신 제어권을 포기하였다. TPEV_SENDONLY 이벤트의 수신자는 데이터를 송신할 수는 있지만 수신자가 제어권을 넘길 때까지는 어떤 데이터도 수신할 수 없다.
-
TPEV_SVCERR
대화 시작자에게 수신되는 이 이벤트는 대화 종속자가 tpreturn() 수행 중에 에러가 발생하였음을 알린다. 예를 들어 tpreturn()에 잘못된 파라미터들이 전달되었거나, 서비스가 다른 종속자들과 연결을 유지하고 있는 동안에 tpreturn()이 호출되었을 수 있다. 이 경우 반환 코드나 데이터 일부는 사용이 불가능하다. 대화형 연결이 종료되고 cd는 더 이상 유효하지 않다. 만약 이 이벤트가 수신자의 트랜잭션 과정에서 발생했다면, 그 트랜잭션은 rollback된다.
-
TPEV_SVCFAIL
대화 시작자에게 수신되는 이 이벤트는 상대편인 대화 종속자 서비스가 애플리케이션에서 실패로 서비스를 종료하였음을 알린다. TPFAIL로 tpreturn()을 호출하였다. 대화 종속자 서비스가 tpreturn()을 호출했을 때 통신 제어권을 가지고 있었다면, 서비스는 연결된 상대방에게 데이터를 전달할 수 있다. 서비스가 종료하면서 서버 프로세스는 대화형 연결을 끊는다. 그러므로 cd는 더 이상 유효하지 않다. 만약 이 이벤트가 수신자의 트랜잭션 과정에서 발생하였다면 그 트랜잭션은 rollback된다.
-
TPEV_SVCSUCC
대화 시작자에게 수신되는 이 이벤트는 상대편인 대화 종속자 서비스가 성공적으로 종료하였음을 알린다. TPSUCCESS로 tpreturn()을 호출하였다.
-
-
반환값
revent 값이 TREV_SVCSUCC이거나 TREV_SVCFAIL인 경우 tpreturn()으로 전달되는 tpurcode 전역 변수는 애플리케이션에서 정의한 값을 갖게 된다. 그렇지 않으면 -1을 반환하고, tperrno에 에러 상황에 해당하는 값이 설정된다. 에러 없이 이벤트가 존재한다면 tprecv()는 -1을 반환하고, tperrno는 [TPEEVENT]가 된다.
-
오류
tprecv()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEBADDESC]
구별자(cd)가 유효하지 않다.
[TPEBLOCK]
TPNOBLOCK가 설정된 상태에서 블로킹 상황이 발생하였다.
[TPEEVENT]
이벤트가 발생하였고 revent로 이벤트 유형을 알 수 있다.
[TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 *data가 가리키는 버퍼가 tpalloc()으로 되지 않았거나 flags가 유효하지 않은 경우이다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
[TPEOTYPE]
입력된 버퍼의 유형이나 하위 유형이 호출자가 알지 못하는 것이거나, flags로 TPNOCHANGE가 설정되었는데 *data의 유형 및 하위 유형이 입력되는 버퍼의 유형 및 하위 유형과 일치하지 않는다. 이런 경우 *data의 내용과 *len은 모두 아무 변화 없다. 대화형 통신이 트랜잭션의 한 부분이라면, 그 트랜잭션은 응답이 무시되었기 때문에 rollback된다.
에러가 발생하면, cd에 대한 이벤트는 무시되고 대화형 통신 상태는 보장할 수 없다. 따라서 호출자는 대화형 통신을 종료해야 한다.
[TPEPROTO]
tprecv()가 부적절한 상황에서 호출되었다. 예를 들어 송신자 모드에서 사용한 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPETIME]
타임아웃이 발생한 경우로 함수 호출자가 트랜잭션 모드에 있다면, 트랜잭션 타임아웃이 발생하였고 그 트랜잭션은 rollback된다. 트랜잭션 모드가 아니고 TPNOTIME과 TPNOBLOCK 어느 것도 지정되지 않았다면, 블록 타임아웃이 발생하였다. 이 두 경우에 *data의 내용과 len은 변경되지 않는다. 트랜잭션 타임아웃이 발생하였다면, 트랜잭션이 rollback될 때까지 대화형 통신으로 메시지를 송신하거나 수신하는 일 또는 새로운 연결을 시작하는 일은 모두 [TPETIME] 에러로 실패하게 된다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include “../sdl/demo.s” main(int argc,char* argv[]) { int ret, cd; struct dat *buf; long revent, len; if (argc!=3) {error processing } ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=(struct dat *)tpalloc(“STRUCT”, “dat”, 0); if (buf==NULL) { error processing } strcpy(buf->sdata, argv[1]); data process…. cd=tpconnect(“SERVICE”, buf, 0, TPSENDONLY); if (cd==-1) { error processing } strcpy(buf->sdata, argv[2]); data process…. ret=tpsend(cd, buf, 0,TPRECVONLY,&revent); if (ret==-1) { error processing } ret=tprecv(cd,(char**)&buf,&len,TPNOTIME,&revent); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpalloc(), tpconnect(), tpdiscon(), tpsend()
5.4. tpdiscon
서버와 클라이언트에서 대화형 통신의 연결을 종료하는 함수이다. tpconnect()으로 연결한 서비스일 경우 극히 예외적인 경우에 연결을 즉시 종료하고 연결된 상대방에게 TPEV_DISCONIMM 이벤트를 발생시킨다.
tpdiscon()은 단지 대화형 통신을 시작한 측에서만 호출할 수 있고 구별자(descriptor)를 제공한 서비스에서는 호출할 수 없다. 대화형 서비스와 통신하는 프로그램은 대화형 통신을 종료할 수 있는데, 올바른 결과를 보장하기 위해서는 서비스에서 tpreturn()으로 연결을 종료하는 것이 좋다.
tpdiscon()은 연결을 강제적으로 종료시킨다. 강제로 종료되는 경우 목적지에 전달되지 못한 일부 데이터는 분실될 수 있다. tpdiscon()은 연결된 상대방 프로그램이 호출자의 트랜잭션에 참여하고 있는 상황에서 호출될 수도 있다. 이 경우 트랜잭션은 취소되고 데이터는 상실될 수 있다. tpdiscon()을 호출하는 함수 호출자가 통신 제어권을 가져야 할 필요는 없다.
-
프로토타입
# include <atmi.h> int tpdiscon (int cd)
-
파라미터
파라미터 설명 cd
tpconnect()에서 반환한 참조 구별자(descriptor)이다.
-
반환값
반환값 설명 -1
함수 호출에 에러가 발생한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpdiscon()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEBADDESC]
cd가 유효하지 않거나 이미 대화형 서비스에서 사용되고 있는 구별자이다.
[TPETIME]
타임아웃이 발생하였다. cd는 더 이상 유효하지 않다.
[TPEPROTO]
tpdiscon()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <stdlib.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { int ret, cd; char *buf long len, revent; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... cd=tpconnect(“SERVICE”,buf,0,TPRECVONLY); if (cd==-1) { error processing } data process.... ret=tprecv(cd, (char **)&buf, &len, TPNOFLAGS, &revent); if (ret==-1 && revent != TPEV_SENDONLY && revent != TPEV_SVCSUCC) { error processing } printf(“received data = %s\n”, buf); if (atoi(buf)>90) { ret=tpdiscon(cd); if (ret==-1) {error processing } tpfree(buf); tpend(); exit(1); } data process.... tpfree(buf); tpend(); }
-
관련함수
tpconnect(), tprecv(), tpreturn(), tpsend()
6. 비요청 메시지 처리
비요청 메시지 처리 함수는 메시지를 무조건 보내거나, 일방적으로 보내는 메시지를 처리하기 위한 함수이다. 서버에서 보내는 일방적인 메시지(tpbroadcast())를 항상 모든 클라이언트가 받을 수 있는 것은 아니다. 비요청 메시지를 받기 위해서는 먼저 클라이언트가 Tmax에 접속되어 있어야 하고, Tmax에 접속할 때 비요청 메시지를 받겠다는 정보를 주어야 한다.
tpstart()를 호출할 때 사용하는 TPSTART_T 구조체의 flags 값을 TPUNSOL_POLL이나 TPUNSOL_HND로 설정해야만 서버에서 보내는 일방적인 데이터를 Tmax가 처리한다.
6.1. tpsetunsol
클라이언트에서 사용되는 함수로 비요청 수신 메시지를 처리하는 루틴 설정한다. 시스템이 비요청 메시지를 통지받는 데 사용되는 방법은 애플리케이션에 임의로 결정되며, 이는 각 클라이언트별로 변경이 가능하다.
tpsetunsol()이 처음으로 호출되기 전에 Tmax 라이브러리에 의해 수신된 비요청 메시지는 무시된다. NULL 함수 포인터의 tpsetunsol() 호출도 마찬가지로 무시된다. 호출로 전달된 함수 포인터는 주어진 파라미터 정의에 적합해야 한다.
-
프로토타입
# include <atmi.h> Unsolfunc *tpsetunsol (void ( *disp ) ( char *data, long len, long flags ))
-
파라미터
파라미터 설명 data
수신된 유형 버퍼를 지시한다. 데이터도 수반되지 않았다면 data는 NULL이 될 수 있다. data가 클라이언트가 알지 못하는 버퍼 유형 및 하위 유형인 경우 데이터는 이해되지 못한다. 애플리케이션은 data를 제거할 수 없으며, 대신 시스템이 이를 제거하고 데이터 영역을 무효화하여 반환한다.
len
데이터의 길이를 나타낸다.
flags
현재 사용되지 않는다.
-
반환값
반환값 설명 포인터 / NULL
함수 호출에 성공한 경우이다.
-
포인터: 이전에 설정된 비요청 메시지 처리 루틴의 포인터를 반환한다.
-
NULL: 이전에 어떤 메시지 처리 함수도 설정되지 않았음을 나타내는 것으로 성공적인 반환이다.
TPUNSOLERR
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
-
오류
tpsetunsol()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEPROTO]
tpsetunsol()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include “../sdl/demo.s” void get_unsol(char *data, long len, long flags) { printf(“get unsolicited data = %s\n”, data); data process.... } void main(int argc, char *argv[]) { int ret; char *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } ret=tpsetupsol_flag(TPUNSOL_HND); if (ret==-1) { error processing } ret=tpsetunsol(get_unsol); if (ret==TPUNSOLERR) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; data process... ret=tpcall(“SERVICE”, buf, 20, (char **)&buf, &len, TPNOFLAGS); if (ret==-1) { error processing } data process... tpfree((char *)buf); tpend(); }
-
관련함수
tpstart(), tpend(), tpgetunsol()
6.2. tpgetunsol
클라이언트의 요청 없이 일방적으로 전달받은 메시지를 처리하는 함수이다. 메시지를 보내는 측에서 tpbroadcast() 또는 tpsendtoci(), tppost()를 통해 전달한다.
ttpgetunsol() 호출 전에 전달된 일방적인 메시지들은 무시된다. tpgetunsol()을 통해 비요청 메시지를 받으려면 tpstart()를 통해 Tmax 시스템에 연결할 때에 flags를 TPUNSOL_POLL이나 TPUNSOL_HND로 지정해야 한다. tpgetunsol()이 프로그램에 호출되면 tpstart()의 flags가 TPUNSOL_IGN로 설정되었다 하더라도 내부적으로 TPUNSOL_POLL로 전환되어 서버로부터 비요청 메시지를 받게 된다.
-
프로토타입
#include <tmaxapi.h> int tpgetunsol (int type, char **data, long *len, long flags)
-
파라미터
파라미터 설명 type
서버에서 전달된 메시지의 형식으로 UNSOL_TPPOST, UNSOL_TPBROADCAST, UNSOL_TPSENDTOCLI 등이 있다.
data
전달된 메시지에 대한 포인터이다. 클라이언트가 알지 못하는 버퍼 유형 및 하위 유형(subtype)일 수 있는데 이 경우 data는 사용할 수 없다.
len
메시지의 총 길이이다.
flags
메시지의 블로킹(blocking) 처리 여부를 결정한다.
flags로 사용 가능한 값은 다음과 같다.
-
TPBLOCK
tpgetunsol()을 호출할 때에 블로킹 상태로 일방적인 메시지가 올 때까지 기다린다.
-
TPNOCHANGE
수신된 응답 버퍼와 *data가 가리키는 버퍼의 유형이 다르다면 *data의 버퍼 유형은 수신자가 인식할 수 있는 한도 내에서 수신된 응답 버퍼의 유형으로 변경된다. flags가 설정된 경우 *data가 가리키는 버퍼의 유형은 변경되지 못한다. 수신된 응답 버퍼의 유형 및 하위 유형은 *data가 가리키는 버퍼의 유형 및 하위 유형과 반드시 일치해야 한다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기다리겠다는 것을 의미한다. 트랜잭션 모드에서 tpgetrply()를 수행한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용하는 flags로 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. TPSIGRSTRT flag와 TPBLOCK flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
TPGETANY
입력값으로 구별자(cd)를 무시하고, 이에 상관없이 수신 가능한 응답을 반환하도록 한다. cd는 반환된 응답에 대한 호출 구별자가 된다. 응답이 없으면 일반적으로 tpgetrply()는 응답이 도착할 때까지 대기한다.
-
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 상황에 해당하는 값이 설정된다.
-
오류
tpgetunsol()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEPROTO]
tpgetunsol()가 부적절한 상황에서 호출되었다. tpstart()가 수행되지 않았으며 TMAX_ACTIVATE_AUTO_TPSTART=N 옵션이 설정되었을 경우 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <string.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... while(1) { ret=tp_sleep(2); if (ret==-1) { error processing } if (ret==0) printf(“nothing happened\n”); else { ret=tpgetunsol(UNSOL_TPSENDTOCLI, (char **)&buf, &len, TPNOCHANGE); if (ret==-1) { error processing } printf(“received data : %s\n”, buf); } data process.... if (strncmp(buf, “end”, 3)==0) break; } data process.... tpfree(buf); tpend(); }
-
관련함수
tpbroadcast(), tpsetunsol(), tpstart(), tpend()
7. 타임아웃 변경
타임아웃을 변경하는 경우 사용하는 함수를 설명한다.
7.1. tpset_timeout
서버와 클라이언트에서 사용되는 함수로 서버에 설정되어 있는 서비스 제한시간인 블록 타임아웃을 설정한다. tpset_timeout()으로 서비스 제한시간을 설정한 경우 설정한 시간 동안 서비스 요청에 대한 응답을 기다린다. 설정한 시간이 지나도록 응답을 수신하지 못하면 타임아웃 에러가 발생하고, 요청한 서비스에 대한 응답을 기다리지 않고 서비스 실패로 반환된다.
tpset_timeout()는 해당 함수가 호출된 이후의 서비스 요청들에 적용된다. 다시 tpset_timeout()이 호출되거나, 클라이언트나 서버 프로세스가 종료될 때까지 함수는 유효하다. tpset_timeout()이 사용되지 않는다면 블록 타임아웃으로 Tmax 환경 파일에 설정된 BLOCKTIME이 적용된다.
-
프로토타입
#include <tmaxapi.h> int tpset_timeout (int sec)
-
파라미터
파라미터 설명 sec
블록 타임아웃 시간을 초 단위로 설정한다.
-
반환값
반환값 설명 0
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpset_timeout()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *sndbuf, *rcvbuf; long sndlen, rcvlen; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } sndbuf = (char *)tpalloc(“CARRAY”, NULL, 20); if (sndbuf==NULL) {error processing }; rcvbuf = (char *)tpalloc(“CARRAY”, NULL, 20); if (rcvbuf==NULL) {error processing }; data process.... sndbuf=strlen(sndbuf); ret=tpset_timeout(4); if (ret==-1) { error processing } ret=tpcall(“SERVICE”, sndbuf, sndlen, &rcvbuf, &rcvlen, TPNOCHANGE); if (ret==-1) { error processing } data process.... tpfree((char *)sndbuf); tpfree((char *)rcvbuf); tpend(); }
7.2. tpsetsvctimeout
서버에서 사용되는 함수로 서버에 설정되어 있는 서비스 타임아웃 시간을 설정한다. tpsetsvctimeout()으로 서비스 시간을 설정한 경우 이 함수가 호출된 이후 설정한 시간(초) 동안 서비스 요청에 대한 응답을 기다린다. 설정한 시간이 지나도록 응답을 수신하지 못하면 타임아웃 에러가 발생하고, 요청한 서비스에 대한 응답을 기다리지 않고 서비스 실패로 반환된다.
-
프로토타입
#include <tmaxapi.h> int tpsetsvctimeout (int sec, long flags)
-
파라미터
파라미터 설명 sec
서비스 타임아웃 시간을 초 단위로 설정한다.
flags
현재에는 사용하지 않는다.
-
반환값
반환값 설명 0
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpsetsvctimeout()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <stdlib.h> #include <usrinc/tmaxapi.h> #include <usrinc/tdlcall.h> TOUPPER(TPSVCINFO *msg) { int i; if ( tpsetsvctimeout(10, 0) < 0 ) ; //error handle code printf("TOUPPER service is started!\n"); sleep(15); printf("INPUT : data=%s\n", msg->data); for (i = 0; i < msg->len; i++) msg->data[i] = toupper(msg->data[i]); printf("OUTPUT: data=%s\n", msg->data); tpreturn(TPSUCCESS,0,(char *)msg->data, 0,0); }
8. 버퍼 관리
서로 다른 하드웨어나 운영체계에 있어서 메모리 할당 방식과 데이터 유형의 크기 차이로 송신한 데이터와 다른 데이터 값을 가질 수 있다. 따라서 일반적인 클라이언트/서버 환경에서 이기종 간의 통신은 주로 문자형으로 변환하여 통신하게 된다. 이것은 네트워크 부하를 증가시키는 원인이 되기도 한다.
버퍼 관리에 사용되는 API에 대해 설명한다.
8.1. tpalloc
서버와 클라이언트에서 유형 버퍼(typed buffer)를 할당하는 함수로 C 라이브러리의 malloc()이나 realloc() 또는 free()와 함께 사용될 수 없다. 예를 들어 tpalloc()으로 할당된 버퍼를 free()로 제거할 수 없다. 이 경우에는 tpfree()를 사용한다.
tpalloc()은 type으로 지정된 유형의 버퍼를 할당하고 그에 대한 포인터를 반환한다. 유형에 따라 subtype과 size는 선택적으로 지정할 수 있다. 일부 버퍼 유형은 사용되기 전에 초기화가 필요하기 때문에 tpalloc()은 버퍼를 할당한 후 이를 초기화하여 반환한다. 그러므로 호출자에게 반환된 버퍼는 즉시 사용 가능하다. 초기화 작업에 실패하면, tpalloc()은 버퍼를 0값으로 초기화하지 못하고 할당된 버퍼는 제거(free)된다.
메모리 동적 할당시 1 Gbyte 제한이 있다.
-
프로토타입
# include <atmi.h> char * tpalloc (char *type, char *subtype, long size)
-
파라미터
파라미터 설명 type
버퍼 유형으로 다음 중에 하나를 지정한다.
-
STRING : NULL로 끝나는 문자열의 데이터를 전송할 때 사용한다.
-
CARRAY, X_OCTET : 길이가 지정된 문자형의 데이터를 전송할 때 사용한다.
-
STRUCT, X_C_TYPE : C 언어 구조체 타입의 데이터를 전송할 때 사용한다.
-
X_COMMON : char, int, long만 가능한 C 구조체일 때 사용한다.
-
FDL(FIELD 버퍼) : 데이터를 식별자와 식별자에 해당하는 값 형태로 저장할 때 사용한다.
subtype
type이 STRUCT, X_C_TYPE, X_COMMON인 경우에 반드시 subtype을 지정해야 한다. type의 처음 8Byte와 subtype의 처음 16Byte만이 사용되고 지정된 길이를 초과해서 사용하면 초과한 길이는 무시된다. 지정된 버퍼 유형이 하위 유형을 사용하지 않는다면, subtype은 무시되고 보통 NULL이 사용된다.
할당된 버퍼의 크기는 기본 크기(1024Byte) 이상이다.
size
버퍼 크기로 CARRAY와 X_OCTET에서는 반드시 지정하여야 하며 이를 제외하고는 생략 가능하다. 0으로 지정하면 각 버퍼의 기본 크기가 사용된다.
STRING, STRUCT, X_C_TYPE, X_COMMON의 기본 크기는 1024Byte이다.
CARRAY의 기본 크기는 0이지만 버퍼를 할당할 때에는 반드시 0보다 커야 한다.
-
-
반환값
반환값 설명 버퍼 포인터
함수 호출에 성공한 경우이다. 적절한 유형 버퍼에 대한 포인터를 반환한다.
NULL
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpalloc()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 NULL 형식인 경우에 발생한다.
[TPENOENT]
알 수 없는 유형 또는 하위 유형이다. STRUCT 버퍼 유형인 경우 하위 유형이(구조체의 태그명) SDLFILE에 존재하지 않는 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
메모리를 할당 받지 못하는 운영 시스템에 에러가 발생하였다.
[TPEOTYPE]
요청되는 서버의 자료형이 구조체 버퍼인데 해당 서버가 컴파일할 때 구조체 파일과 함께 컴파일이 되지 않은 경우에 발생한다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include “../sdl/demo.s” void main(int argc, char *argv[]) { int ret; struct data *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret<0) { error processing } buf=(struct data *)tpalloc(“STRUCT”, “data”,0); data process.... ret=tpcall(“SERVICE”, (char *)sndbuf, 0, (char **)&rcvbuf, &len, TPNOFLAGS); if (ret<0) {error processing } data process.... tpfree((char *)buf); tpend(); }
-
관련함수
tpfree(), tprealloc(), tptypes()
8.2. tprealloc
서버와 클라이언트에서 유형 버퍼의 재할당하는 함수로 ptr이 가리키는 버퍼의 크기를 Byte로 재할당하고, 버퍼가 변경되었을 경우 새 버퍼에 대한 포인터를 반환한다.
tpalloc()과 동일하게 버퍼의 크기는 기본 사이즈(1024Byte) 이상이다. 버퍼의 유형은 재할당된 후에도 동일하게 유지된다. 함수가 성공적으로 반환되면, 반환된 포인터가 버퍼를 참조하기 위해서 사용되고 ptr은 더 이상 사용될 수 없다. 재할당된 버퍼의 크기가 축소되는 경우 원래 ptr의 내용은 보장할 수 없다.
일부 버퍼 유형들은 사용되기 전에 초기화될 필요가 있다. tprealloc()은 버퍼 재할당 이후 다시 초기화하여 반환한다. 그렇기 때문에 호출자에게 반환된 버퍼는 즉시 사용 가능하다. 버퍼가 재초기화에 실패하면 tprealloc()은 NULL을 반환하고 ptr이 지시하는 버퍼의 내용은 유효하지 않다.
-
프로토타입
# include <atmi.h> char * tprealloc (char *ptr, long size)
-
파라미터
파라미터 설명 ptr
할당할 버퍼에 대한 포인터이다.
size
할당할 버퍼의 크기이다.
-
반환값
반환값 설명 버퍼 포인터
함수 호출에 성공한 경우이다. 적절한 유형 버퍼에 대한 포인터를 반환한다.
NULL
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tprealloc()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 ptr이 가리키는 버퍼가 tpalloc()으로 할당된 것이 아닌 경우이다.
[TPEPROTO]
tprealloc()이 부적절한 상황에서 호출되었다.
[TPENOENT]
ptr이 가리키는 버퍼가 tpalloc()으로 할당되지 않은 버퍼이다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { char *buf; buf=tpalloc(“STRING”,NULL,10); if (buf==NULL) { error processing } buf=tprealloc(buf,20); /* ok */ if (buf==NULL) { error processing } buf=”test”; buf=tprealloc(buf,30); /*error : TPEINVAL */ if (buf==NULL) { error processing } }
-
관련함수
tpalloc(), tpfree(), tptypes()
C 라이브러리의 malloc(), realloc() 또는 free()와 함께 사용될 수 없다. 예를 들어 tprealloc()으로 할당된 버퍼를 free()로 해제할 수 없다. |
8.3. tpfree
서버와 클라이언트에서 유형 버퍼(typed buffer)에 할당된 메모리를 해제하는 함수로 이전에 tpalloc()이나 tprealloc()으로 얻어진 버퍼를 해제한다.
-
프로토타입
# include <atmi.h> void tpfree(char *ptr)
-
파라미터
파라미터 설명 ptr
tpalloc()이나 tprealloc()으로 얻어진 버퍼에 대한 포인터이다.
ptr이 NULL이면 아무 일도 일어나지 않는다. ptr이 유형 버퍼를 가리키지 않거나, tpfree()로 이미 해제된 공간을 가리킨다면 그 결과는 알 수 없다. 서비스 루틴 내부에서 ptr이 서비스 루틴에게 전달된 버퍼라면 tpfree()는 버퍼를 해제하지 않고 그냥 반환한다. 버퍼를 제거하는 과정에서 일부 버퍼 유형은 관련 데이터나 상태 정보를 해제할 필요가 있다. tpfree()는 버퍼를 해제하기 전에 이와 관련된 정보도 제거한다.
tpfree()가 수행되면 ptr은 XATMI 루틴에 파라미터로 전달될 수 없으며 어떤 다른 방식으로 사용될 수 없다.
-
반환값
tpfree()는 함수 호출자에게 아무런 값도 반환하지 않는다.
-
예제
#include <usrinc/atmi.h> #include <stdio.h> #include “../sdl/demo.s” void main(int argc, char *argv[]) { int ret; struct data *buf; char *message, *message2; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=(struct data *)tpalloc(“STRUCT”, “data”,0); if (buf==NULL) { error processing } message=tpalloc(“STRING”, NULL, 0); if (message==NULL) { error processing } message2=tpalloc(“CARRAY”, NULL, 20); if (message==NULL) { error processing } data process.... tpfree((char *)buf); tpfree(message); tpfree((char *)message2); tpend(); }
-
관련함수
tpalloc(), tprealloc()
tpfree()는 C 라이브러리의 malloc(), realloc() 또는 free()와 함께 사용될 수 없다. tpalloc()으로 할당된 버퍼는 free()로 해제할 수 없다. |
8.4. tptypes
서버와 클라이언트에서 사용되는 함수로 버퍼의 유형 및 하위 유형에 대한 정보를 제공한다. tptypes()는 ptr로 데이터 버퍼에 대한 포인터를 입력받아, type과 subtype에 각각 버퍼의 유형과 하위 유형을 반환한다.
-
프로토타입
#include <atmi.h> long tptypes (char *ptr, char *type, char *subtype)
-
파라미터
파라미터 설명 ptr
반드시 tpalloc()으로 할당된 버퍼를 가리켜야 한다.
type, subtype
NULL이 아니라면 가리키고 있는 문자열에 각각 버퍼의 type과 subtype 이름을 갖는다.
subtype이 존재하지 않으면 subtype이 가리키는 배열은 NULL 스트링을 포함하고 있다. 이름이 최대 길이라면 문자열은 NULL로 끝나지 않는다(최대 길이는 type은 8자, subtype은 16자이다).
type의 처음 8Byte와 subtype의 처음 16Byte만이 유효한 값을 갖는다.
-
반환값
반환값 설명 버퍼크기
함수 호출에 성공하는 경우이다.
-1
함수 호출에 실패하는 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tptypes()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 ptr이 가리키는 버퍼가 tpalloc()으로 할당되지 않은 경우에 발생한다.
[TPEPROTO]
함수가 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include “../sdl/demo.s” main(int argc, char *argv[]) { int ret; struct sel_o *rcvbuf; char type[9], subtype[17]; long size; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf=(struct sel_o*)tpalloc(“STRUCT”,”sel_o”,0); if (buf==NULL) {error processing }; size =tptypes((char*)buf, type,subtype); if (size==-1) {error processing }; printf (“buf : size %d, type %s, subtype %s\n\n”, size, type, subtype); /*rcvbuf : size 1024, type STRUCT, subtype sel_o */ data process... tpfree((char *)buf); tpend(); }
-
관련함수
tpalloc(), tpfree(), tprealloc()
9. 트랜잭션 관리
트랜잭션 관리에 관련된 함수를 설명한다.
9.1. tx_begin
서버와 클라이언트에서 사용하는 함수로 호출하면 전역 트랜잭션을 시작되고 함수 호출자는 트랜잭션 모드가 된다. 호출 프로세스가 트랜잭션을 시작하기 전에, 먼저 tx_open()으로 자원 관리자와 연결되어 있어야 한다. tx_begin()은 호출자가 이미 트랜잭션 모드에 있거나 또는 tx_open()이 호출되지 않았다면 실패하게 되고, [TX_PROTOCOL_ERROR]를 반환한다.
트랜잭션이 시작되면 호출 프로세스는 현재 트랜잭션을 완료하기 위해서 tx_commit()이나 tx_rollback()를 호출한다. 트랜잭션을 시작하기 위하여 반드시 tx_begin()을 직접적으로 호출할 필요가 없는 연속(chaining) 트랜잭션의 경우도 존재한다. 자세한 내용은 tx_commit과 tx_rollback을 참고한다.
-
프로토타입
#include <tx.h> int tx_begin (void)
-
반환값
반환값 설명 TX_OK
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우이다.
-
오류
tx_begin()이 정상적으로 수행되지 않을 경우 다음의 에러 코드를 반환한다.
에러 코드 설명 [TX_OUTSIDE]
현재 호출 프로세스가 외부의 전역 트랜잭션에 참여하고 있기 때문에 트랜잭션 관리자가 전역 트랜잭션을 시작할 수 없다. 그러한 작업들이 모두 완료되어야만 전역 트랜잭션을 시작할 수 있다. 참여하고 있는 트랜잭션에는 영향을 주지 않는다.
[TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 이미 트랜잭션 모드에 있는 경우에 발생한다. 현재 트랜잭션에는 영향을 주지 않는다.
[TX_ERROR]
트랜잭션 관리자 또는 리소스 관리자가 트랜잭션을 시작하는 중에 일시적으로 에러가 발생하였다. 에러가 반환되면 호출자는 더 이상 트랜잭션 모드에 있지 않다. 에러의 정확한 원인은 제품의 특성에 따라 결정된다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자나 리소스 관리자는 더이상 애플리케이션을 위하여 작업을 실행할 수 없다. 에러가 반환되면 호출자는 더 이상 트랜잭션 모드에 있지 않다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tx.h> void main(int argc, char *argv[]) { char *buf; int ret,cd; long len, revent; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; data process.… ret=tx_set_transaction_timeout( 5 ); if (ret<0) { error processing } ret=tx_begin(); if (ret<0) { error processing } cd = tpconnect(“SERVICE”, buf, 20, TPRECVONLY); if (cd==-1) { error processing } ret = tprecv(cd, (char **)&buf, &len,TPNOFLAGS, &revent)}; if (ret < 0 && revent != TPEV_SVCSUCC) tx_rollback(); else tx_commit(); data process.... tpfree((char *)buf); tpend(); }
-
관련함수
tx_commit(), tx_open(), tx_rollback(), tx_set_transaction_timeout()
9.2. tx_commit
서버와 클라이언트에서 사용하는 함수로 전역 트랜잭션을 commit한다.
transaction_control이 TX_UNCHAINED인 경우 tx_commit()이 반환할 때 호출자는 더 이상 트랜잭션 모드에 있지 않다. transaction_control 특성이 TX_CHAINED인 경우 tx_commit()이 반환할 때 호출자는 새로운 트랜잭션을 위하여 트랜잭션 모드로 남아 있는다. transaction_control 특성에 대한 자세한 내용은 tx_set_transaction_control을 참고한다.
-
프로토타입
# include <tx.h> int tx_commit(void)
-
반환값
반환값 설명 TX_OK
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우 에러 코드를 반환한다.
-
오류
tx_commit()이 정상적으로 수행되지 않을 경우 다음의 에러 코드를 반환한다.
에러 코드 설명 [TX_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭션이 성공적으로 commit되었다. 그러나 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.
[TX_ROLLBACK]
트랜잭션이 rollback되었다. transaction_control 특성이 TX_CHAINED라면 새로운 트랜잭션이 시작된다.
[TX_ROLLBACK_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭션이 rollback되었다. 이 에러가 발생하는 경우 새로운 트랜잭션은 시작될 수 없고 호출자는 더이상 트랜잭션 모드에 있지 않다.
[TX_HAZARD]
에러때문에 트랜잭션이 일부는 commit되거나 일부는 rollback된다. transaction_control 특성이 TX_CHAINED라면 새로운 트랜잭션이 시작된다.
[TX_HAZARD_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭션이 일부는 commit되거나 일부는 rollback된다. 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.
[TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 트랜잭션 모드에 있지 않는 경우에 발생한다. 트랜잭션과 관련된 호출자의 상태는 변함없다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자나 리소스 관리자가 더 이상 애플리케이션을 위해 작업할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다. 트랜잭션과 관련된 호출자의 상태는 알 수 없다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tx.h> void main(int argc, char *argv[]) { char *buf; int ret,cd; long len, revent; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; data process.… ret=tx_set_transaction_timeout( 5 ); if (ret<0) { error processing } ret=tx_begin(); if (ret<0) { error processing } cd = tpconnect(“SERVICE”, buf, 20, TPRECVONLY); if (cd==-1) { error processing } ret = tprecv(cd, (char **)&buf, &len,TPNOFLAGS, &revent)}; if (ret < 0 && revent != TPEV_SVCSUCC) tx_rollback(); else tx_commit(); data process.... tpfree((char *)buf); tpend(); }
-
관련함수
tx_begin(), tx_set_commit_return(), tx_set_transaction_control(), tx_set_transaction_timeout()
9.3. tx_info
서버와 클라이언트에서 전역 트랜잭션 정보를 반환하는 함수로 info가 가리키는 구조체를 통하여 전역 트랜잭션 정보를 알려준다. 또한, 호출자가 현재 트랜잭션 모드에 있는지 여부를 알려주는 값을 반환한다.
-
프로토타입
#include <tx.h> int tx_info (TXINFO *info)
-
파라미터
info가 NULL이 아니라면 info가 가리키는 TXINFO 구조체는 전역 트랜잭션에 관한 정보가 된다.
TXINFO 구조체는 아래와 같이 구성되어 있다.
struct TXINFO { XID xid; COMMIT_RETURN when_return; TRANSACTION_CONTROL transaction_control; TRANSACTION_TIMEOUT transaction_timeout; TRANSACTION_STATE transaction_state; };
tx_info()가 트랜잭션 모드에서 호출된다면 xid는 현재 트랜잭션 branch id가 되고 transaction_state는 현재 트랜잭션의 상태가 된다. 호출자가 트랜잭션 모드에 있지 않다면, xid는 NULL XID가 된다. 자세한 내용은 <tx.h>를 참고한다.
호출자가 트랜잭션 모드에 있는 것과 관계없이 when_return, transaction_control 그리고 transaction_timeout은 commit_return의 현재 설정과 transaction_control 특성 그리고 초 단위의 트랜잭션 타임아웃 값을 포함한다.
반환된 트랜잭션 타임아웃 값은 다음 트랜잭션이 시작될 때부터 사용된다. 현재 트랜잭션이 시작된 후에 tx_set_transaction_timeout() 호출을 통해 트랜잭션 타임아웃값을 변경했을 수도 있기 때문에 호출자의 현재 전역 트랜잭션에 대한 타임아웃 값이 아닐 수도 있다. info가 NULL이라면 TXINFO 구조체는 반환되지 않는다.
같은 전역 트랜잭션 내에서 계속적인 tx_info() 호출은 동일한 gtrid(전역 트랜잭션 구분자)의 XID 제공을 보장한다. 하지만 반드시 동일한 bqual(로컬 트랜잭션 구분자)을 보장하지는 않는다. XID는 동일하지 않을 수 있다.
-
반환값
반환값 설명 1
호출자가 트랜잭션 모드에 있는 경우 함수 호출에 성공한 경우이다.
0
호출자가 트랜잭션 모드에 있지 않은 경우 함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우로 에러 코드를 반환한다.
-
오류
tx_info()가 정상적으로 수행되지 않을 경우 다음의 에러 코드를 반환한다.
에러 코드 설명 [TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 아직 tx_open()을 호출하지 않은 경우에 발생한다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자는 더 이상 애플리케이션을 위한 작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.
-
예제
#include <stdio.h> #include <string.h> #include <usrinc/atmi.h> #include <usrinc/tx.h> void main(int argc, char *argv[]) { int ret; long len; char *buf; TXINFO info; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; data process.... ret=tx_begin(); if (ret<0) { error processing } ret=tpcall(“SERVICE”, buf, 20, (char **)&buf, &len, TPNOFLAGS); if (ret==-1) { error processing } if (tx_info(&info)==1) printf(“In transaction \n”); else printf(“Not in transaction \n”); if (strncmp(buf, “err”, 3)==0) tx_rollback(); else tx_commit(); data process.... tpfree((char *)buf); tpend(); }
-
관련함수
tx_open(), tx_set_commit_return(), tx_set_transaction_control(), tx_set_transaction_timeout()
9.4. tx_rollback
서버와 클라이언트에서 사용하는 함수로 전역 트랜잭션을 rollback한다.
transaction_control 특성이 TX_UNCHAINED인 경우 tx_rollback()이 반환할 때 호출자는 더 이상 트랜잭션 모드에 있지 않다. transaction_control 특성이 TX_CHAINED인 경우 tx_rollback()이 반환할 때 호출자는 새로운 트랜잭션을 위하여 트랜잭션 모드로 남아 있는다. transaction_control 특성에 대한 자세한 내용은 tx_set_transaction_control을 참고한다.
-
프로토타입
#include <tx.h> int tx_rollback(void)
-
반환값
반환값 설명 TX_OK
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우로 에러 코드를 반환한다.
-
오류
tx_rollback()이 정상적으로 수행되지 않을 경우 다음의 에러 코드를 반환한다.
에러 코드 설명 [TX_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭션이 rollback된다. 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.
[TX_MIXED]
트랜잭션이 일부는 commit되었고 일부는 rollback된다. transaction_control 특성이 TX_CHAINED라면 새로운 트랜잭션을 시작한다.
[TX_MIXED_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭션이 일부는 commit되고 일부는 rollback된다. 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.
[TX_HAZARD]
에러로 인해 트랜잭션이 일부는 commit되거나 일부는 rollback된다. transaction_control 특성이 TX_CHAINED라면 새로운 트랜잭션이 시작된다.
[TX_HAZARD_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때에만 발생하는 에러로 트랜잭션이 일부는 commit되거나 일부는 rollback된다. 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.
[TX_COMMITTED]
트랜잭션이 독자적으로 commit된다.
transaction_control 특성이 TX_CHAINED인 경우 새로운 트랜잭션이 시작된다.
[TX_COMMITTED_NO_BEGIN]
transaction_control 특성이 TX_CHAINED일 때만 발생될 수 있는 에러로 트랜잭션이 독자적으로 commit된다. 새로운 트랜잭션은 시작될 수 없고 호출자는 더 이상 트랜잭션 모드에 있지 않다.
[TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 트랜잭션 모드에 있지 않은 경우에 발생한다. 트랜잭션과 관련된 호출자의 상태는 변함없다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자나 리소스 관리자는 더 이상 애플리케이션을 위한 작업을 실행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다. 트랜잭션과 관련된 호출자의 상태는 알 수 없다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tx.h> void main(int argc, char *argv[]) { char *buf; int ret,cd; long len, revent; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; data process.… ret=tx_set_transaction_timeout( 5 ); if (ret<0) { error processing } ret=tx_begin(); if (ret<0) { error processing } cd = tpconnect(“SERVICE”, buf, 20, TPRECVONLY); if (cd==-1) { error processing } ret = tprecv(cd, (char **)&buf, &len,TPNOFLAGS, &revent)}; if (ret < 0 && revent != TPEV_SVCSUCC) tx_rollback(); else tx_commit(); data process.... tpfree((char *)buf); tpend(); }
-
관련함수
tx_begin(), tx_set_transaction_control(), tx_set_transaction_timeout()
9.5. tx_set_transaction_timeout
서버와 클라이언트에서 transaction_timeout 설정 함수로 transaction_timeout 특성을 타임아웃 값으로 설정한다. 설정된 값은 트랜잭션 타임아웃이 발생하기 전에 트랜잭션을 완료해야 하는 시간으로 tx_begin()과 tx_commit() 또는 tx_begin()과 tx_rollback() 사이의 시간이다.
tx_set_transaction_timeout()는 함수 호출자가 트랜잭션 모드에 있는지와 상관없이 호출 가능하다. tx_set_transaction_timeout()이 트랜잭션 모드에서 호출된다면 새로운 타임아웃 값은 다음 트랜잭션 때부터 적용된다.
-
프로토타입
# include <tx.h> int tx_set_transaction_timeout (TRANSACTION_TIMEOUT timeout)
-
파라미터
파라미터 설명 timeout
트랜잭션 타임아웃이 발생하기 전까지 허용된 시간을 초 단위 숫자로 지정한다. 설정값은 시스템별로 정의된 long 타입의 최댓값까지 설정 가능하다. 초기값은 0으로 설정되고 타임아웃 제한이 없음을 의미한다.
-
반환값
반환값 설명 TX_OK
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우로 에러 코드를 반환한다.
-
오류
tx_set_transaction_timeout()은 기존의 transaction_timeout 값의 변경 없이 다음의 에러 코드를 반환한다.
에러 코드 설명 [TX_EINVAL]
지정된 타임아웃 값이 유효하지 않다.
[TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 아직 tx_open()을 호출하지 않은 경우에 발생한다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자가 더 이상 애플리케이션을 위한 작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.
-
예제
#include <usrinc/atmi.h> #include <usrinc/tx.h> void main(int argc, char *argv[]) { int ret; long len; char *buf; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) {error processing }; ret=tx_set_transaction_timeout( 5 ); if (ret<0) { error processing } ret=tx_begin(); if (ret<0) { error processing } ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf, &len, TPNOFLAGS); if (ret == -1) { tx_rollback(); error processing } data process …. ret = tx_commit(); if (ret < 0) { error processing } data process... tpfree((char *)buf); tpend(); }
-
관련함수
tx_begin(), tx_commit(), tx_open(), tx_rollback(), tx_info()
9.6. tx_set_transaction_control
서버와 클라이언트에서 transaction_control 특성을 control 값으로 설정하는 함수이다.
transaction_control 특성은 tx_commit()과 tx_rollback()이 호출자에게 반환하기 전에 새로운 트랜잭션을 시작할지 여부를 결정한다. tx_set_transaction_control()는 애플리케이션이 트랜잭션 모드에 있는지 여부와 관계없이 호출 가능하다. 이 설정은 tx_set_transaction_control() 재호출에 의해 변경될 때까지 유효하게 적용된다.
-
프로토타입
# include <tx.h> int tx_set_transaction_control(TRANSACTION_CONTROL control)
-
파라미터
control로 사용 가능한 값은 다음과 같다.
설정값 설명 TX_UNCHAINED
tx_commit()과 tx_rollback()이 함수 호출자에게 반환하기 전에 새로운 트랜잭션을 시작하지 않도록 한다. 이 경우 호출자는 새로운 트랜잭션을 시작하려면 tx_begin()을 실행해야 한다. transaction_control 특성의 초기 설정값이다.
TX_CHAINED
tx_commit()과 tx_rollback()이 호출자에게 반환하기 전에 새로운 트랜잭션을 시작하도록 한다.
-
반환값
반환값 설명 TX_OK
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우로 에러 코드를 반환한다.
-
오류
tx_set_transaction_control()은 기존의 transaction_control 특성 변경없이 다음의 에러 코드를 반환한다.
에러 코드 설명 [TX_EINVAL]
control 파라미터가 TX_UNCHAINED나 TX_CHAINED로 설정되지 않았다.
[TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 함수 호출자가 아직 tx_open()을 호출하지 않은 경우에 발생한다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자는 더 이상 애플리케이션을 위한 작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.
-
예제
#include <usrinc/atmi.h> #include <usrinc/tx.h> int main(int argc, char *argv[]) { int ret; long len; char *buf; ret = tpstart((TPSTART_T *)NULL); if (ret == -1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; ret = tx_set_transaction_timeout(5); if (ret < 0){ error processing } ret = tx_set_transaciont_control(TX_UNCHAINED); if (ret < 0){ error processing } ret = tx_begin(); if (ret < 0) { error processing } data process.... ret = tpcall(“SERVICE1”, (char *)buf, strlen(buf), (char **)&buf, &len, TPNOFLAGS); if (ret == -1) { tx_rollback(); error processing } data process... ret = tpcall(“SERVICE2”, (char *)buf, strlen(buf), (char **)&buf, &len, TPNOFLAGS); if (ret == -1) { tx_rollback(); error processing } data process …. ret = tx_commit(); if (ret < 0) { error processing } data process... tpfree((char *)buf); tpend(); }
-
관련함수
tx_begin(), tx_commit(), tx_open(), tx_rollback(), tx_info()
9.7. tx_set_commit_return
서버와 클라이언트에서 commit_return 특성을 설정하는 함수로 when_return 값으로 반환한다.
commit_return 특성은 tx_commit()이 함수 호출자에게 제어권을 반환하는 방식을 결정한다. tx_set_commit_return()은 함수 호출자가 트랜잭션 모드에 있는 것과 관계없이 호출 가능하다. 설정은 tx_set_commit_return() 재호출로 인해 변경될 때까지 유효하게 적용된다. commit_return 특성에 대한 초기 설정은 실행에 따라 다르다.
-
프로토타입
#include <tx.h> int tx_set_commit_return (COMMIT_RETURN when_return)
-
파라미터
when_return으로 사용 가능한 값은 다음과 같다.
설정값 설명 TX_COMMIT_DECISION_LOGGED
tx_commit()이 2PC(2 Phase Commit) 프로토콜 중 첫 번째 단계에서 로깅된 후 두 번째 단계는 완료되기 전에 반환한다. tx_commit()이 호출자에게 보다 빠르게 응답할 수 있지만, 트랜잭션이 독자적(heuristic)인 결과를 갖게 될 위험이 있고, 그런 경우에 호출자는 tx_commit()으로부터 반환된 코드로 발생된 상황을 제대로 알 수 없다.
정상적인 경우에 첫 번째 단계에서 트랜잭션을 commit하기로 한 트랜잭션 참여자는 두 번째 단계에서 제대로 commit하게 된다. 그러나 네트워크나 노드 장애가 길게 지속되는 등의 비정상적인 경우에는 2개 단계의 완료가 가능하지 않을 수 있으며, 독자적인 결과를 초래할 수도 있다. 트랜잭션 관리자는 옵션으로 이 특성을 지원하지 않도록 선택할 수 있으며, 이때 이 값을 지원하지 않음을 나타내는 [TX_NOT_SUPPORTED] 값으로 반환한다.
TX_COMMIT_COMPLETED
2PC 프로토콜이 완전하게 종료된 후에 tx_commit()이 반환한다. 설정은 트랜잭션이 독자적인(heuristic) 결과를 갖게 되었거나 또는 그럴 가능성을 알리는 반환 코드를 tx_commit()의 호출자에게 전달한다. 트랜잭션 관리자는 옵션으로 이 특징을 지원하지 않도록 선택할 수 있으며, 이 값을 지원하지 않음을 나타내는 [TX_NOT_SUP-PORTED] 값으로 반환한다.
-
반환값
성공적으로 작업이 완료된 경우 tx_set_commit_return()은 음이 아닌 값의 [TX_OK]를 반환한다.
when_return이 TX_COMMIT_COMPLETED 또는 TX_COMMIT_DECISION_LOGGED으로 설정되지 않았다면, 함수는 음이 아닌 값으로 [TX_NOT_SUPPORTED]를 반환하고, commit_return 특성은 현재 적용되고 있는 값이 여전히 유효하다. 트랜잭션 관리자는 when_return을 최소한 TX_COMMIT_COMPLETED나 TX_COMMIT_DECISION_LOGGED 중의 하나로는 설정해야 한다.
함수 호출에 실패한 경우 에러 코드를 반환한다.
-
오류
tx_set_commit_return()는 commit_return 특성 설정 변경 없이 음수값 중 하나를 반환한다.
에러 코드 설명 [TX_EINVAL]
when_return이 TX_COMMIT_COMPLETED나 TX_COMMIT_DECISION_LOGGED로 설정되어 있지 않다.
[TX_PROTOCOL_ERROR]
함수가 부적절한 상황에서 호출되었다. 예를 들어 호출자가 아직 tx_open()을 호출하지 않은 경우이다.
[TX_FAIL]
치명적인 에러가 발생하여 트랜잭션 관리자는 더 이상 애플리케이션을 위한 작업을 수행할 수 없다. 에러의 정확한 원인은 제품의 특성에 따라 다르다.
-
예제
#include <usrinc/tx.h> int main(int argc, char *argv[]) { int ret; long len; char *buf; ret = tpstart((TPSTART_T *)NULL); if (ret == -1) { error processing } buf = (char *)tpalloc(“CARRAY”, NULL, 20); if (buf==NULL) {error processing }; ret = tx_set_transaction_timeout(5); if (ret < 0){ error processing } ret = tx_set_commit_return(TX_COMMIT_COMPLETED); if (ret < 0){ error processing } ret = tx_begin(); if (ret < 0){ error processing } data process.... ret = tpcall(“SERVICE1”, (char *)buf, strlen(buf), (char **)&buf, &len, TPNOFLAGS); if (ret == -1) { tx_rollback(); error processing } data process... ret = tpcall(“SERVICE2”, (char *)buf, strlen(buf), (char **)&buf, &len, TPNOFLAGS); if (ret == -1) { tx_rollback(); error processing } data process …. ret = tx_commit(); if (ret < 0) { error processing } data process... tpfree((char *)buf); tpend(); }
-
관련함수
tx_commit(), tx_open(), tx_info()
10. RQ 시스템
본 절에서는 RQ에서 사용하는 함수에 대해 설명한다. Tmax 시스템은 신뢰성 있는 큐를 위하여 RQ를 제공하는데, RQ에 데이터를 Enqueue/Dequeue하는 큐 관리 프로세스로 ENQSVR이 동작한다(Windows NT 또는 2000 환경에서는 사용할 수 없다).
시스템의 장애나 오류로 인한 서비스가 불가능한 상태에서도 큐에 저장된 데이터는 정합성을 보장받을 수 있다. 주로 여러 대의 서버가 WAN 환경으로 구축되었거나 업무 폭주로 인한 작업량이 많은 경우 RQ를 이용하면 데이터의 신뢰성을 보장받으면서 업무가 처리될 수 있다.
10.1. tpenq
서버와 클라이언트에서 RQ에 데이터를 저장하는 함수로 Tmax 시스템은 시스템의 장애나 에러로 인한 서비스가 불가능한 상태에서도 RQ에 저장된 데이터는 정합성을 보장할 수 있다. RQ에 데이터를 저장해 두었다가 여러 가지 상황으로 시스템이 다운되고 복구 이후 다시 실행되면 이전에 처리하지 못한 데이터를 계속해서 처리할 수 있다.
tpcall()이나 tpacall()로 서비스를 요청한 경우 해당 서비스가 수행할 데이터가 누적되어 있다면 서비스를 요청한 데이터도 대기(waiting)한다. 이때 시스템의 장애나 에러로 인해 시스템이 다운되면 대기 중인 데이터는 분실된다. 이러한 문제점을 보안하고 데이터의 정합성을 보장할 수 있도록 tpenq()는 서비스를 요청하는 경우 데이터를 RQ에 저장한다. 트랜잭션 모드에서 수행해도 트랜잭션 모드에서 제외되기 때문에 트랜잭션 모드에서 함수를 수행 도중 에러가 발생해도 트랜잭션에는 영향을 미치지 않는다.
-
프로토타입
# include <tmaxapi.h> int tpenq (char *qname, char *svc, char *data, long len, long flags)
-
파라미터
파라미터 설명 qname
qname은 데이터를 저장할 RQ의 이름으로 config 파일에 등록된 이름이어야 한다.
svc
데이터를 RQ에 저장하고, svc 이름이 NULL이 아니면 즉시 서비스를 요청한다.
svc 이름이 NULL이면 데이터는 RQ에 저장되고 서비스는 수행되지 않는다. 이 경우 나중에 tpdeq()를 이용하여 서비스를 요청해야 한다. svc로 명명된 서비스가 없거나 또는 서비스를 수행하고 처리 결과를 받지 않은 상태에서 시스템 장애가 발생할 경우에는 이 데이터는 내부적으로 Fail 큐에 저장된다. 데이터는 tpdeq()로 서비스를 재요청하거나 에러 처리를 해야 한다.
data
NULL 값인 경우를 제외하고 반드시 tpalloc()으로 할당된 버퍼에 대한 포인터이어야 한다. data의 유형(type)과 하위 유형(subtype)은 svc가 지원하는 유형이어야 한다.
len
송신하는 데이터의 길이이다.
-
data가 가리키는 버퍼가 특별한 길이 명시가 필요없는 버퍼 유형(STRING, STRUCT, X_COMMON, X_C_TYPE)인 경우 len은 무시되고 0이 사용된다.
-
data가 가리키는 버퍼가 길이 명시가 반드시 필요한 버퍼 유형(X_OCTET, CARRAY, MULTI STRUCTURE)인 경우 len은 0이 될 수 없다.
-
data가 NULL인 경우 len은 무시되고 데이터 없이 서비스 요청이 송신된다.
flags
flags에 사용 가능한 값은 다음과 같다.
-
TPRQS
svc가 NULL이 아닌 경우 svc로 명명된 서비스를 요청하고, 처리 결과를 RQ에 저장된다. 서비스 처리 결과는 tpdeq()를 이용해서 받는다. svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않는다.
-
TPNOREPLY
svc가 NULL이 아닌 경우 svc로 명명된 서비스는 요청하지만, 처리 결과는 RQ에 저장하지 않겠다는 의미이다. svc가 NULL인 경우 데이터는 단지 RQ에 저장되고 서비스는 수행하지 않는다.
-
TPFUNC
서비스별 RQ 데이터를 관리할 때 사용한다. flags가 설정되지 않았다면 처음 tpenq()를 통해 저장된 데이터가 제거된다. 데이터가 저장되기 전에 제거해야 할 경우에는 tpenq() 호출할 때 TPFUNC를 같이 설정한다.
-
0(zero)
서비스 처리 결과를 RQ에 저장하지 않고, 함수 호출자가 접속되어 있는 Tmax 시스템의 클라이언트 버퍼에 저장한다. 서비스는 RQ를 통해 요구하지만 결과는 tpcall()처럼 함수 호출자가 접속한 클라이언트의 버퍼에서 가져올 때 사용한다. 0(zero)flags가 설정되면 나중에 처리 결과를 받기 위해서는 tpdeq() 호출할 때 flags에 0(zero)을 설정해야 한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpenq()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나, 또는 flags가 유효하지 않은 경우에 발생한다.
[TPENOENT]
존재하지 않는 qname이 사용되었다.
[TPEQFULL]
지속적인 서비스 결과로 지정된 큐의 크기를 넘는 경우에 발생한다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpenq()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) { error processing } data process.... ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpdeq(), tpqstat()
10.2. tpdeq
서버와 클라이언트에서 RQ로부터 데이터를 로드하는 함수로 tpenq()를 이용하여 서비스를 요청한 결과를 받거나 서비스명을 NULL로 해서 저장한 데이터를 읽는다. tpenq()를 호출할 때 flags에 TPNOREPLY를 설정하면 서비스는 결과를 받을 수 없다. 그러므로 트랜잭션 모드에서 tpdeq()를 수행 도중 에러가 발생해도 트랜잭션에는 영향을 미치지 않는다.
-
프로토타입
# include <tmaxapi.h> int tpdeq (char *qname, char *svc, char **data, long *len, long flags)
-
파라미터
파라미터 설명 qname
데이터를 저장할 RQ의 이름으로 config 파일에 등록된 이름이어야 한다.
svc
tpenq()를 호출하는 경우 svc에 전달한 이름이어야 한다. 서비스명으로 tpenq()를 호출한 경우 서비스가 자동 요청되고, 결과가 RQ에 저장된다. 서비스 결과를 받기 위해서는 tpdeq()도 동일한 서비스명을 입력해야 한다.
서비스명을 NULL로 tpenq()를 호출한 경우 tpdeq()도 동일한 서비스명을 입력한다. 서비스명이 NULL인 경우 서비스명에 상관없이 큐에 쌓여있는 모든 데이터를 하나씩 로드할 수 있다.
tpenq()의 경우 에러나 시스템 장애로 인해 Fail 큐에 저장된 데이터를 tpdeq()하기 위해서는 svc에 _rq_sub_queue_name[TMAX_FAIL_QUEUE]를 주고 deq해야 한다.
*data
tpalloc()에 의해 할당된 버퍼에 대한 포인터이다. 함수가 성공적으로 반환되면 *data는 수신된 데이터가 저장된다.
len
tpdeq()가 성공적으로 수신한 데이터의 길이이다. tpdeq()는 필요하다면 응답 내용이 지정된 버퍼에 수신될 수 있도록 버퍼 크기를 증가시킨다.
len은 *data의 데이터의 길이로 *data는 수신 데이터가 커서 변경될 수도 있고, 이 외에 다른 이유에 의해서도 변경될 수 있다. len이 호출 전 버퍼의 총 크기보다 크다면, len이 그 버퍼의 새로운 크기가 된다. len이 0으로 반환되었다면, 어떤 데이터도 수신되지 않고 *data와 len이 지시하는 버퍼 모두 아무런 변화가 없다.
*data나 len이 NULL이 되는 것은 에러이다.
flags
flags에 사용 가능한 값은 다음과 같다.
-
TPRQS
RQ에서 데이터를 가져올 때 사용된다. reply 큐로부터 서비스의 결과를 가져오기 위해서 설정된다.
-
TPFUNC
서비스별 RQ 데이터를 관리할 때 사용한다. flags가 설정되지 않았다면 처음 tpenq()를 통해 저장된 데이터가 제거된다. 데이터가 저장되기 전에 제거해야 할 경우에는 tpenq() 호출할 때 TPFUNC를 같이 설정한다.
-
TPBLOCK
tpdeq() 호출할 때 블록 타임아웃 시간 동안 메시지가 올 때까지 기다린다.
-
TPNOTIME
TPBLOCK과 함께 사용되면 블록 타임아웃 시간에 관계없이 응답이 올 때까지 기다리게 된다.
-
0(zero)
데이터를 자신이 접속한 클라이언트의 버퍼에서 가져오려고 할 때 사용한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpdeq()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나 또는 flags가 유효하지 않은 경우에 발생한다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEMATCH]
서비스명이 잘못되었거나 제거할 데이터가 없는 경우 해당 조건을 만족하는 제거할 데이터를 찾지 못했다.
[TPENOENT]
존재하지 않는 qname이 사용되었다.
[TPEPROTO]
tpdeq()이 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) { error processing } data process.... ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS); if (ret==-1) { error processing } data process.... tpfree(buf); tpend(); }
-
관련함수
tpenq(), tpqstat()
10.3. tpqstat
서버와 클라이언트에서 사용되는 함수로 RQ에 저장된 데이터의 통계를 요청한다. RQ는 내부적으로 _fail queue, _request queue, _reply queue의 3부분으로 구성되어 있다. flags 값을 이용하여 각 큐에 저장된 데이터 통계를 구할 수 있다.
-
프로토타입
# include <tmaxapi.h> int tpqstat (char *qname, long flags)
-
파라미터
파라미터 설명 qname
Tmax 환경 파일에 등록된 RQ 이름을 나타낸다.
flags
대상 데이터의 type을 설정한다.
flags로 사용 가능한 값은 다음과 같다.
-
0(TMAX_ANY_QUEUE) _fail queue, _request queue, _reply queue의 데이터 통계를 낼 때 사용한다.
-
1(TMAX_FAIL_QUEUE) : _fail queue의 데이터 통계를 낼 때 사용한다.
-
2(TMAX_REQ_QUEUE) : _request queue의 데이터 통계를 낼 때 사용한다.
-
3(TMAX_RPLY_QUEUE) : _reply queue의 데이터 통계를 낼 때 사용한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpqstat()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 qname이 NULL이거나 qname에 해당하는 큐가 없거나 flags가 유효하지 않은 경우에 발생한다.
[TPEPROTO]
tpqstat()가 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret, i; char *buf; if (argc!=2) { error processing } ret=tpstart((TPSTART_T *)NULL); if (ret==-1) {error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } strcpy(buf, argv[1]); data process… ret=tpenq(“RQ”, NULL, (char *)buf, strlen(buf), TPRQS); if (ret==-1) {error processing } printf(“qstat :”); for (i=0;i<4;i++) { ret=tpqstat(“rq”, i); if (ret==-1) {error processing } printf(“ %d”,ret); /* qstat : 1 0 0 1 */ } printf(“\n”); data process… ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) {error processing } printf(”qstat :”); for (i=0;i<4;i++) { ret=tpqstat(“rq”, i); if (ret==-1) {error processing } printf(” %d”,ret); /* qstat : 2 0 0 2 */ } printf(“\n”); tpfree((char *)buf); tpend(); }
-
관련함수
tpenq(), tpdeq()
10.4. tpextsvcname
서버와 클라이언트에서 tpdeq()로 RQ에서 데이터를 읽은 경우 해당 데이터의 서비스명을 알려고 할 때 사용한다. tpextsvcname()은 _Fail 큐에 저장되어 있는 데이터를 tpdeq()로 읽은 경우에 사용한다.
-
프로토타입
# include <tmaxapi.h> int tpextsvcname (char *data, char *svc)
-
파라미터
파라미터 설명 data
tpdeq()를 이용하여 RQ로부터 읽은 데이터가 저장되어 있는 포인터로 tpalloc()으로 할당된다.
svc
해당 데이터의 서비스명을 받아오기 위한 포인터이다.
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpextsvcname()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들면 data에 tpalloc()으로 할당되지 않은 버퍼가 전달되는 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> #include <usrinc/tmaxapi.h> void main(int argc, char *argv[]) { int ret; char *buf, *svc_name; long len; ret=tpstart((TPSTART_T *)NULL); if (ret==-1) { error processing } buf = (char *)tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process.... ret=tpenq(“RQ”, “SERVICE”, (char *)buf, strlen(buf), TPRQS); if (ret==-1) { error processing } data process.... ret=tpdeq(“RQ”, “SERVICE”, (char **)&buf, (long *)&len, TPRQS); if (ret==-1) { error processing } ret=tpextsvcname(buf, svc_name); if (ret==-1) { error processing } printf(“svc name : %s ,”,svc_name); data process.... tpfree(buf); tpend(); }
-
관련함수
tpenq(), tpdeq()
11. 이벤트를 활용하는 API
Tmax는 이벤트를 통해 다수의 클라이언트뿐만 아니라 서비스 루틴에도 메시지를 보낼 수 있다. 모든 클라이언트와 서비스 루틴은 개발자 임의로 이벤트에 가입하거나 취소할 수 있고 이벤트를 발생시킬 수 있다. 또한 하나의 이벤트에 중복 가입하거나 동시에 여러 가지 이벤트에 가입할 수도 있다.
발생된 이벤트에 의한 이벤트 데이터 전송과 그에 따른 결과는 트랜잭션의 범주에 들지 않으므로 주의하도록 한다. |
11.1. tpsubscribe
서버와 클라이언트에서 사용되는 함수로 특정 사건의 발생시점에 클라이언트나 서버로부터 데이터를 전달받기 위한 요청을 등록한다. eventname에 해당하는 사건이 발생하면 알려 달라는 것을 Tmax 시스템에 등록하는 함수이다.
-
프로토타입
# include <tmaxapi.h> long tpsubscribe(char *eventname, char *filter, TPEVCTL *ctl, long flags)
-
파라미터
파라미터 설명 eventname
NULL로 끝나는 63자 이내의 문자열로 메시지를 받을 사건의 이름을 지정한다.
와일드 카드 문자나 partial-matching 등은 지원되지 않으며 전체 문자열이 일치하는 이름의 사건만을 등록할 수 있다.
filter
앞으로 확장을 위하여 예약해 놓은 것으로 NULL을 지정한다.
ctl
사건이 발생하는 경우 메시지를 받아오는 방식을 지정하는 구조체로 tpsubscribe()의 주체에 따라 다른 동작을 한다. 클라이언트에서 tpsubscribe()를 사용한 경우에 ctl은 항상 NULL이어야 하며 메시지는 클라이언트에게 unsolicited 데이터 형태로 전달된다. 클라이언트는 tpsubscribe()이나 tpgetunsol() 등의 함수를 사용하여 전달된 데이터를 처리한다.
flags
현재 TPNOTIME만 의미가 있다.
서버에서 tpsubscribe()를 행하는 경우에는 ctl이 NULL이면 안되고 아래와 같은 내용을 가져야 한다.
struct tpevctl { long ctl_flags; long post_flags; char svc[XATMI_SERVICE_NAME_LENGTH]; char qname[RQ_NAME_LENGTH]; }; typedef struct tpevctl TPEVCTL;
멤버 설명 ctl_flags
앞으로 확장을 위하여 생성된 것으로 현재는 0으로 채워야한다.
post_flags
앞으로 확장을 위하여 생성된 것으로 현재는 0으로 채워야한다.
qname
qname을 사용할 경우 메시지는 tpenq(qname, NULL, data, len, TPNOFLAGS)를 통해 RQ에 저장된다.
svc
svc를 사용할 경우 메시지는 tpacall(svc, data, len, TPNOREPLY)과 유사한 방식으로 서버에게 전달되며 서버의 반환값은 무시된다. qname과 svc는 둘 중 한 가지만을 사용한다.
-
반환값
반환값 설명 descriptor
함수 호출에 성공한 경우이다. tpunsubscribe()를 호출할 때에 사용될 descriptor를 반환한다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpsubscribe()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 클라이언트의 경우 네트워크 에러가 가장 빈번히 발생한다.
[TPEOS]
OS 레벨에서 발생하는 에러로 메모리 할당과 같은 문제를 포함한다.
[TPEINVAL]
잘못된 파라미터를 사용하는 경우 발생하는 에러이다.
[TPENOENT]
TPEVCTL 구조체의 qname이나 svc에 해당하는 RQ나 서버가 존재하지 않는 경우이다.
[TPEPROTO]
클라이언트와 서버에서 ctl이 NULL이 아닌 경우이다.
[TPETIME]
타임아웃이 발생한 경우이다.
-
관련함수
tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()
11.2. tpunsubscribe
서버와 클라이언트에서 사용하는 함수로 tpsubscribe()로 등록한 특정 사건에 대한 요청을 해제한다. 등록된 모든 요청이 해제되는 경우 Tmax 시스템은 해당 사건의 테이블을 삭제한다.
-
프로토타입
# include <tmaxapi.h> int tpunsubscribe(long sd, long flags)
-
파라미터
파라미터 설명 sd
tpsubscribe()로 등록할 때 받아온 반환값이다.
flags
현재 TPNOTIME만 의미가 있다.
-
반환값
반환값 설명 양수
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpunsubscribe()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPESYSTEM]
Tmax 시스템에서 에러가 발생하였다. 클라이언트의 경우 네트워크 에러가 가장 많이 발생한다.
[TPEOS]
OS 레벨의 에러 발생한 경우로 메모리 할당과 같은 문제를 포함한다.
[TPEINVAL]
잘못된 파라미터를 사용한 경우 발생한다.
[TPETIME]
타임아웃이 발생한 경우이다.
-
관련함수
tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()
11.3. tppost
서버와 클라이언트에서 특정 사건을 발생시키고 메시지를 전달하는 함수이다. tppost()는 이름이 eventname인 사건에 tpsubscribe()로 등록된 모든 클라이언트와 서버 프로세스에게 사건의 발생을 알리고 필요할 경우 메시지를 전달한다.
-
프로토타입
# include <tmaxapi.h> int tppost(char *eventname, char *data, long len, long flags)
-
파라미터
파라미터 설명 eventname
NULL로 끝나는 63자 이내의 문자열로 발생할 사건의 이름을 의미한다. 와일드 카드 문자나 partial-matching 등은 지원되지 않는다.
data
보낼 메시지에 대한 포인터로 tpalloc()에 의해 할당된 버퍼이어야 한다.
len
송신하는 버퍼의 길이이다.
-
data의 길이 명시가 필요없는 버퍼를 가리키는 경우 len은 무시되고 보통 0이 사용된다.
-
data의 길이 명시가 반드시 필요한 버퍼를 가리키는 경우 len은 0이 될 수 없다.
-
data가 NULL인 경우 len은 무시된다.
flags
현재 TPNOTIME만 의미가 있다.
-
-
반환값
반환값 설명 양수
함수 호출에 성공한 경우이다.
음수
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tppost()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPESYSTEM]
Tmax 시스템 에러가 발생한 경우로 클라이언트의 경우 네트워크 에러가 가장 빈번하다.
[TPEOS]
OS 레벨의 에러 발생한 경우로 메모리 할당과 같은 문제를 포함한다.
[TPEINVAL]
잘못된 파라미터를 사용하는 경우이다.
[TPENOENT]
tpsubscribe()의 경우 TPEVCTL 구조체의 qname이나 svc에 해당하는 RQ나 서버가 존재하지 않는 경우이다.
[TPEPROTO]
클라이언트에서 tpsubscribe()를 수행하는 경우 ctl이 NULL이 아닌 경우나 서버에서 수행하는 경우 ctl이 NULL인 경우 발생한다.
[TPETIME]
타임아웃이 발생한다.
-
관련함수
tpsetunsol(), tpsetunsol_flag(), tpgetunsol(), tpacall(), tpenq()
12. Broadcast/Multicast
Tmax는 다양한 방법으로 클라이언트에게 데이터를 전달할 수 있다. 관리나 기타 개발의 목적으로 다수의 클라이언트에게 데이터를 보내야 하는 경우 모든 클라이언트의 ID를 관리하여 각각 메시지를 보내는 것도 한 방법이겠지만 시스템의 동시 사용자가 많은 경우 효율적인 방법이 되지 않는다.
다수의 클라이언트를 몇 개의 그룹으로 구분할 수 있다면 하나의 API를 이용하여 해당되는 모든 클라이언트에게 메시지를 보내는 것이 가능하다. Tmax는 클라이언트의 접속 정보를 활용하거나 이벤트를 이용하는 방법으로 브로드 캐스트 및 멀티 캐스트를 구현하고 있다. 2개의 방식 모두 일반적인 의미의 브로드 캐스트 및 멀티 캐스트가 가능하지만 구분의 편의상 전자를 브로드 캐스트 API, 후자를 멀티 캐스트 API라고 부른다.
12.1. tpbroadcast
Tmax 시스템에 등록된 클라이언트들에게 요청하지 않은 메시지를 송신하는 함수이다. 메시지가 송신 가능한 클라이언트들은 tpstart()로 이미 Tmax 시스템에 연결되어 있어야 하며, 이때 클라이언트의 이름과 flags가 알맞게 정의되어야 한다. 비요청 메시지를 받기 위해서는 비요청 메시지를 받겠다는 정보를 주어야 한다. tpstart()를 사용하는 경우 TPSTART_T 구조체의 flags 값을 TPUNSOL_POLL이나 TPUNSOL_HND로 설정해야만 비요청 메시지를 받을 수 있다.
-
프로토타입
# include <atmi.h> int tpbroadcast (char *nodename, char *usrname, char *cltname, char *data, long len, long flags)
-
파라미터
파라미터 설명 nodename,
usrname,
cltname
대상 클라이언트를 선택하는 데 사용되는 논리적인 이름으로 63자 이내여야 한다. 이름 지정에는 물음표(?)나 애스터리스크(*) 등의 와일드 카드(wildcards) 문자들이 사용될 수 있다. NULL 값이 사용될 수 있는데, 이는 모든 클라이언트에 대응되는 와일드 카드로 동작한다. 길이가 0인 string 인수는 길이가 0인 클라이언트 이름과만 대응된다.
cltname으로 사용되는 이름은 클라이언트가 tpstart()를 이용하여 처음 Tmax 시스템에 연결할 때 등록하는 클라이언트 이름이다.
data
반드시 tpalloc()에 의해 이전에 할당된 버퍼를 사용해야 한다.
len
송신할 데이터 길이이다.
-
data가 가리키는 버퍼가 특별한 길이 명시가 필요 없는 STRING, STRUCT, X_COMMON, X_C_TYPE 의 버퍼 유형이라면 len은 무시되고 0이 사용된다.
-
data가 NULL인 경우도 len은 무시된다.
flags
설정 가능한 값은 표 이후에 설명한다.
flags로 사용 가능한 값에 대한 설명이다.
-
TPNOBLOCK
내부 버퍼가 송신 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 요청이 송신되지 않는다.
-
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기한다. 트랜잭션 타임아웃 내에서 tpbroadcast()를 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
-
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용한다. 내부에서 시그널 인터럽트가 발생하여 시스템 함수 호출이 방해될 때 TPSIGRSTRT flag가 설정되어 있으면 BLOCKTIME 시간동안 계속 응답을 기다린다. TPSIGRSTRT flags가 설정되지 않은 경우 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpbroadcast()가 정상적으로 수행되지 않은 경우 어떤 메시지도 클라이언트들에게 송신되지 않으며 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 식별자 길이가 너무 길거나 flags가 유효하지 않은 경우에 발생한다. nodename를 잘못 사용한 경우 tpbroadcast()가 실패하고 TPEINVAL을 반환하게 된다. 그러나 usrname이나 cltname이 잘못된 경우 아무에게도 메시지가 전달되지 않고 단순히 성공인 것으로 수행된다.
[TPETIME]
TPNOBLOCK이나 TPNOTIME이 설정되지 않은 상태에서 블록 타임아웃이 발생하였다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹(blocking) 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
tpbroadcast()가 부적절한 상황에서 호출되었다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <stdio.h> #include <usrinc/atmi.h> void main(int argc, char *argv[]) { int ret; char *buf; TPSTART_T *tpinfo; tpinfo = (TPSTART_T *)tpalloc(“TPSTART”, NULL, sizeof(TPSTART_T)); if (tpinfo==NULL) { error processing } strcpy(tpinfo->cltname, “cli1”); strcpy(tpinfo->usrname, “navis”); ret=tpstart(tpinfo); if (ret==-1) { error processing } buf=tpalloc(“STRING”, NULL, 0); if (buf==NULL) { error processing } data process… tpbroadcast(“tmax”, NULL, NULL, buf, 0, TPNOFLAGS); data process.... tpfree(buf); tpend(); }
-
관련함수
tpalloc(), tpend(), tpstart()
13. 환경 프로그램
개발된 서비스가 일반 사용자를 위한 것일 경우 클라이언트 프로그램은 주로 개인 PC에 많이 사용되는 Windows 환경을 기반으로 하여 개발된다. Tmax는 이를 위해 다양한 개발 툴을 위한 인터페이스를 제공한다. 또한 개발자의 편의를 위해 다양한 종류의 라이브러리를 제공한다. 라이브러리에 따라 API가 추가되었거나 대체되는 API가 있을 수 있다.
Tmax가 지원하는 개발 툴은 PowerBuilder, Delphi, VC++, BC++, VB, VB .Net, C# .Net이며 각 개발 툴에 대한 자세한 사용법은 Tmax Programming Guide (4GL)를 참고한다. |
다음은 지원 라이브러리에 대한 설명이다.
라이브러리 | 설명 |
---|---|
tmax.lib (dll) |
VC++, Delphi, C#에 사용된다. (cdecl) |
tmax4gl. lib (dll) |
BC++, PowerBuilder, VB, VB.Net에 사용된다. (stdcall) |
tmaxmt. lib (dll) |
멀티 스레드 형태를 지원하기 위한 라이브러리이다. (cdecl) |
Wintmax. lib (dll) |
멀티 윈도우를 지원하기 위한 라이브러리이다. (cdecl) |
tmaxce.lib (dll) |
윈도우 ce를 위한 라이브러리이다. (cdecl) |
-
tmaxmt.dll
Windows 프로그래밍 환경에서 사용되는 Message-Driven 방식의 서비스 요청을 위해 2가지 API를 추가하였다. 2개의 API는 거의 동일하며 지정한 Windows로 메시지를 넘기느냐 지정한 Callback 함수로 넘기느냐 하는 차이가 있을 뿐이다. API를 수행할 때마다 스레드를 하나씩 생성하여 메시지를 처리한다. 헤더 파일은 tmaxpi.h를 사용한다.
-
WinTmaxAcall()
-
WinTmaxAcall2()
-
-
WinTmax.dll
프로그래밍 환경에서 사용되는 Message-Driven 방식의 서비스 요청을 위한 API를 추가하였다. 독립적인 스레드를 이용하여 메시지를 처리하므로 tpstart()나 tpend() 대신 WinTmaxStart(), WinTmaxEnd()를 사용한다.
-
WinTmaxStart()
-
WinTmaxEnd()
-
WinTmaxSetContext ()
-
WinTmaxSend ()
tmaxmt.dll과 유사한 방식으로 동작하지만 Tmax 시스템에 자동으로 접속/해제 작업을 하지 않으며 API 당 하나씩 스레드를 생성하는 대신 하나의 스레드로 모든 메시지를 처리한다. 에러 메시지와 비요청 메시지를 처리하기 위해 Window를 별도로 지정하지 않으면 메시지는 무시된다.
디버그 및 관리의 목적으로 MAX_DEBUG 환경변수에 지정된 파일에 로그를 남길 수 있다. 헤더 파일은 WinTmax.h를 사용한다.
-
13.1. WinTmaxAcall
Windows 시스템 환경에서 클라이언트를 사용하는 함수로 MultiThread 환경에서의 비동기 서비스의 송신을 요청한다. MultiThread 환경에서 tpacall()과 같은 기능하는 함수로 새로운 Thread를 만들고, Thread 내에서 tpstart() → tpacall() → tpgetrply()를 수행한다. tpgetrply()를 호출한 후에는 SendMessage(wHandle, msgType, (UINT) &msg, tperrno)를 호출하게 된다.
-
프로토타입
# include <tmaxapi.h> int WinTmaxAcall(TPSTART_T *sinfo, HANDLE wHandle, unsigned int msgtype, char *svc, char *sndbuf, int len, int flags)
-
파라미터
파라미터 설명 sinfo
Tmax 시스템에 클라이언트의 정보를 넘길 필요가 있을 경우 사용하는 구조체로 tpstart()의 파라미터와 동일하다.
wHandle
메시지를 받을 Windows의 핸들러를 지정한다.
msgtype
도착 메시지를 지정한다. 일반적으로 WM_USER를 개발자 임의로 define하여 사용한다. svc Tmax 환경 파일에 등록된 서비스명을 지정한다.
svc
송신을 요청할 서비스를 지정한다.
sndbuf
서비스를 호출할 때 전달되는 데이터로 NULL이 아닌 경우는 반드시 tpalloc()으로 할당된 버퍼를 사용해야 한다.
len
보내는 데이터의 길이를 지정한다. CARRAY, X_OCTET, 구조체 배열 타입일 경우에는 반드시 설정해야 한다.
flags
tpacall()의 flags를 그대로 사용한다. flags로 사용 가능한 값은 다음과 같다.
-
TPBLOCK
flags 없이 tpacall()이 사용되었다면 svc에 호출된 서비스가 없거나 잘못된 결과가 반환되었어도 정상적인 결과가 반환된다. tpgetrply()를 호출할 때 에러가 반환된다. TPBLOCK flags를 이용해 tpacall()을 호출할 경우 서비스 상태의 정상 여부를 확인할 수 있다. -
TPNOTRAN
트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면 tpacall()이 트랜잭션 모드에서 호출되는 경우 flags는 반드시 TPNOTRAN으로 설정해야 한다. tpacall() 호출자가 트랜잭션 모드 상태에서 TPNOTRAN을 설정하여 svc 서비스를 요청했다면 svc 서비스는 트랜잭션 모드에서 제외되어 수행된다. 트랜잭션 모드 내에서의 tpacall()을 호출할 때 TPNOTRAN로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다. TPNOTRAN으로 호출된 서비스가 실패했을 경우 호출자의 트랜잭션에는 영향을 미치지 않는다. -
TPNOREPLY
tpacall()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한다. 결과는 나중에 tpacall()에서 반환한 구별자를 이용하여 tpgetrply()로 결과를 수신한다. flags가 TPNOREPLY로 설정하면 서비스에 대한 응답을 받지 않는겠다고 설정된다. TPNOREPLY로 설정하면 tpacall()은 서비스가 정상적으로 호출되면 0을 반환한다. 함수 호출자가 트랜잭션 모드에 있을 경우에는 반드시 TPNOTRAN flags와 함께 설정해야만 TPNOREPLY flags를 사용할 수 있다. TPNOREPLY flags인 경우 서비스 상태의 정상 여부를 체크하기 위해서는 TPBLOCK flags를 함께 설정해야 한다. TPBLOCK flags를 설정하지 않으면 서비스가 NRDY인 경우에도 에러를 반환하지 않는다. -
TPNOBLOCK
내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패하도록 설정하는 flags이다. TPNOBLOCK flags 설정 없이 tpacall()이 호출된 경우 블로킹(blocking) 상황이 발생하면 함수 호출자는 블로킹(blocking) 상황이 풀리거나 타임아웃(트랜잭션 타임아웃 또는 블록 타임아웃)이 발생할 때까지 대기한다. -
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기하도록 설정하는 flags이다. 트랜잭션 타임아웃 내에서 tpacall()을 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다. -
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용하는 flags로 시스템 함수 호출이 방해될 때 함수 호출이 재실행된다. TPSIGRSTRT가 설정되지 않은 상태에서 시그널 인터럽트가 발생한 경우 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
-
반환값
반환값 설명 1
함수 호출이 성공한 경우이다. 구별자(descriptor)를 반환하고 구별자는 송신된 서비스 요청에 대한 응답을 수신하는 데 사용된다.
-1
함수 호출이 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
WinTmaxAcall()이 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 svc가 NULL이거나 데이터가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나, 또는 flags가 유효하지 않은 경우에 발생한다.
[TPENOENT]
svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.
[TPEITYPE]
data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우 사용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.
[TPELIMIT]
처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에 호출자의 서비스 요청이 송신되지 않았다.
[TPETRAN]
트랜잭션 서비스를 호출할 때 데이터베이스에 문제가 발생하여 xa_start가 실패하였다.
[TPETIME]
타임아웃이 발생하였다. 함수 호출자가 트랜잭션 모드에 있다면 트랜잭션 타임아웃이 발생한 것이며 트랜잭션은 rollback된다. 그렇지 않다면 TPNOTIME이나 TPNOBLOCK이 모두 설정되지 않은 상황에서 블록 타임아웃이 발생한 것이다.
트랜잭션 타임아웃이 발생하는 경우 트랜잭션이 rollback될 때까지 새로운 서비스 요청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두 [TPETIME] 에러로 실패한다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
트랜잭션 모드에서의 TPNOREPLY 서비스를 호출하는 경우 TPNOTRAN flags를 설정하지 않는 경우 등 부적절한 상황에서 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
... #include <usrinc/tmaxapi.h> #define WM_WINTMAX_RECV WM_USER + 1 ... BEGIN_MESSAGE_MAP(CWinTmaxAcall2TestDlg, CDialog) ... ON_MESSAGE(WM_WINTMAX_RECV, OnWinTmaxAcall) ... END_MESSAGE_MAP() BOOL CWinTmaxAcall2TestDlg::OnInitDialog() { CDialog::OnInitDialog(); ... ret = tmaxreadenv(“tmax.env”, “TMAX”); if (ret == -1){ AfxMessageBox(“tmaxreadenv fail...”); return FALSE; } return TRUE; // return TRUE unless you set the focus to a control } void CWinTmaxAcall2TestDlg::OnOK() { ... GetDlgItemText(IDC_EDIT1, m_Input); lstrcpy((LPTSTR)buf, (LPCTSTR)m_Input.operator const char *()); ... buf = tpalloc(“STRING”, NULL, 0); if (buf == NULL){ AfxMessageBox(“buf alloc fail...”); return FALSE; } ret = WinTmaxAcall((TPSTART_T *)NULL, m_hWnd, WM_WINTMAX_RECV, “TOUPPER”, buf, 0, TPNOFLAGS); if (ret == -1){ error processing } } LRESULT CWinTmaxAcall2TestDlg::OnWinTmaxAcall(WPARAM wp, LPARAM lp) { char msg[100]; memset(msg, 0x00, 100); TPSVCINFO *get = (TPSVCINFO *)wp; if (lp < 0){ error processing } ... SetDlgItemText(IDC_EDIT2, get->data); return 0; }
-
관련함수
tpacall(), WinTmaxAcall2()
13.2. WinTmaxAcall2
Windows 시스템 환경에서 클라이언트사용하는 함수로 Multi Thread 환경에서의 비동기 서비스의 송신을 요청한다. MultiThread 환경에서 tpacall()과 같은 기능하는 함수로 새로운 Thread를 생성하고, Thread 내에서 tpstart() → tpacall() → tpgetrply()를 수행한다. tpgetrply()를 호출한 후에는 지정된 Callback 함수로 수신된 데이터를 전달한다.
-
프로토타입
# include <tmaxapi.h> int WinTmaxAcall2(TPSTART_T *sinfo, WinTmaxCallback fn, char *svc, char *sndbuf, int len, int flags)
-
파라미터
파라미터 설명 sinfo
Tmax 시스템에 클라이언트의 정보를 전달할 필요가 있을 경우 사용하는 구조체로, tpstart()의 파라미터와 동일하다.
fn
서비스 요청에 대한 응답을 받을 콜백 함수를 지정한다.
svc
Tmax 환경 파일에 등록된 서비스명을 지정한다.
sndbuf
서비스를 호출할 때 전달되는 데이터로 NULL이 아닌 경우는 반드시 tpalloc() 으로 할당된 버퍼를 사용해야 한다.
len
보내는 데이터의 길이를 지정한다. CARRAY, X_OCTET, 구조체 배열 타입일 경우에는 반드시 설정해야 한다.
flags
tpacall()의 flags를 그대로 사용한다. flags로 사용 가능한 값은 다음과 같다.
-
TPBLOCK
flags 없이 tpacall() 이 사용되었다면 svc에 호출된 서비스가 없거나 잘못된 결과가 반환되었어도 정상적인 결과가 반환된다. tpgetrply()를 호출할 때 에러가 반환된다. TPBLOCK flags를 이용해 tpacall()을 호출할 경우 서비스 상태의 정상 여부를 확인할 수 있다. -
TPNOTRAN
트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면 tpacall()이 트랜잭션 모드에서 호출되는 경우 flags는 반드시 TPNOTRAN으로 설정해야 한다. tpacall() 호출자가 트랜잭션 모드 상태에서 TPNOTRAN을 설정하여 svc 서비스를 요청하였다면, svc 서비스는 트랜잭션 모드에서 제외되어 수행된다. 트랜잭션 모드 내에서의 tpacall()함수를 호출할 때 TPNOTRAN로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다. TPNOTRAN으로 호출된 서비스가 실패했을 경우 호출자의 트랜잭션에는 영향을 미치지 않는다. -
TPNOREPLY
tpacall()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환하고 결과는 나중에 tpacall()에서 반환한 구별자를 이용하여 tpgetrply()로 결과를 수신한다.
flags를 TPNOREPLY로 설정하면 서비스에 대한 응답을 받지 않는겠다고 설정된다. TPNOREPLY로 설정하면 tpacall()은 서비스가 정상적으로 호출되면 0을 반환한다. 함수 호출자가 트랜잭션 모드에 있을 경우에는 반드시 TPNOTRAN flags와 함께 설정해야만 TPNOREPLY flags를 사용할 수 있다. TPNOREPLY flags인 경우 서비스 상태의 정상 여부를 체크하기 위해서는 TPBLOCK flags를 함께 설정해야 한다. TPBLOCK flags를 설정하지 않으면 서비스가 NRDY인 경우에도 에러를 반환하지 않는다. -
TPNOBLOCK
내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패하도록 설정하는 flags이다. TPNOBLOCK flags 설정 없이 tpacall()이 호출된 경우 블로킹 상황이 발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아웃 또는 블록 타임아웃)이 발생할 때까지 대기한다. -
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 대기하도록 설정하는 flags이다. 트랜잭션 타임아웃 내에서 tpacall()을 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다. -
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하는 경우 사용하는 flags로 시스템 함수 호출이 방해될 때 함수 호출이 재실행된다. TPSIGRSTRT가 설정되지 않은 상태에서 시그널 인터럽트가 발생했다면, 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
WinTmaxAcall2()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어 svc가 NULL이거나 data가 tpalloc()으로 할당되지 않은 버퍼를 가리키거나, 또는 flags가 유효하지 않은 경우에 발생한다.
[TPENOENT]
svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.
[TPEITYPE]
data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우 사용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.
[TPELIMIT]
처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에, 호출자의 서비스 요청이 송신되지 않았다.
[TPETRAN]
svc는 트랜잭션을 지원하지 않는 서비스이고, TPNOTRAN이 설정되지 않았다.
[TPETIME]
타임아웃이 발생한 경우로, 함수 호출자가 트랜잭션 모드에 있다면 트랜잭션 타임아웃이 발생한 것이며 트랜잭션은 rollback된다. 그렇지 않다면 TPNOTIME이나 TPNOBLOCK이 모두 설정되지 않은 상황에서 블록 타임아웃이 발생한 것이다. 트랜잭션 타임아웃이 발생한 경우 트랜잭션이 rollback될 때까지 새로운 서비스 요청을 송신한다거나 아직 수신되지 않은 응답을 기다리는 일은 모두 [TPETIME] 에러로 실패한다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
트랜잭션 모드에서의 TPNOREPLY 서비스 호출할 때 TPNOTRAN flags를 설정하지 않는 경우 등 부적절한 상황에서 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
#include <usrinc/tmaxapi.h> #define WM_WINTMAX_RECV WM_USER + 1 int mycallfn(unsigned int, long); ... BEGIN_MESSAGE_MAP(CWinTmaxAcall2TestDlg, CDialog) ... END_MESSAGE_MAP() BOOL CWinTmaxAcall2TestDlg::OnInitDialog() { CDialog::OnInitDialog(); ... ret = tmaxreadenv(“tmax.env”, “TMAX”); if (ret == -1){ AfxMessageBox(“tmaxreadenv fail...”); return FALSE; } return TRUE; // return TRUE unless you set the focus to a control } void CWinTmaxAcall2TestDlg::OnOK() { ... GetDlgItemText(IDC_EDIT1, m_Input); lstrcpy((LPTSTR)buf, (LPCTSTR)m_Input.operator const char *()); ... buf = tpalloc(“STRING”, NULL, 0); if (buf == NULL){ AfxMessageBox(“buf alloc fail...”); return FALSE; } ret = WinTmaxAcall2((TPSTART_T *)NULL, (WinTmaxCallback)mycallfn, “TOUPPER”, (char *)buf, 0, TPNOFLAGS); if (ret == -1){ error processing } } int mycallfn(unsigned int msg, long retval) { TPSVCINFO *svcinfo; char infomsg[30]; memset(infomsg, 0x00, sizeof(infomsg)); svcinfo = (TPSVCINFO *)msg; strncpy(infomsg, svcinfo->data, svcinfo->len); if (retval != 0){ strcpy(infomsg,tpstrerror(retval)); AfxMessageBox(infomsg); return -1; } else { strncpy(infomsg, svcinfo->data, sizeof(infomsg) - 1); AfxMessageBox(infomsg); return 1; } }
-
관련함수
tpacall(),WinTmaxAcall()
13.3. WinTmaxStart
Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 Multi Windows 환경에서 Tmax 시스템과 연결하는 데 사용된다. 기능상으로는 tpstart()와 동일하다. 다중 Thread를 사용하는 경우에는 각각의 Thread별로 WinTmaxStart()를 이용하여 별도의 연결을 맺고 서비스를 호출해야 한다.
-
프로토타입
# include <WinTmax.h> int WinTmaxStart(TPSTART_T *tpinfo)
-
파라미터
TPSTART_T에 대해서는 tpstart를 참고한다.
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
WinTmaxStart()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
파라미터가 유효하지 않다. 예를 들어, tpinfo가 NULL이나 TPSTART_T 구조체에 대한 포인터가 아니다.
[TPEITYPE]
tpinfo가 TPSTART_T 구조체에 대한 포인터가 아니다.
[TPEPROTO]
WinTmaxStart()가 부적절한 곳에서 호출되었다. 예를 들어, 서버 프로그램에서 사용되었거나 이미 연결된 상황에서 재호출된 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생했다. 또는 환경변수 설정이 잘못된 경우이다. 예를 들어 TMAX_HOST_ADDR나 TMAX_HOST_PORT가 잘못 설정되어 연결이 실패한 경우에 발생한다.
-
관련함수
tpstart(), WinTmaxEnd(), WinTmaxSend(), WinTmaxSetContext()
13.4. WinTmaxEnd
Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 Tmax 시스템과 연결을 종료한다. 기능상으로는 tpend()와 같다. 멀티 Thread 환경에서 사용하는 경우는 Thread별로 WinTmaxStart()를 사용하여 연결을 맺게 됨으로써 WinTmaxEnd()도 Thread별로 사용한다.
-
프로토타입
# include <WinTmax.h> int WinTmaxEnd(void)
-
반환값
반환값 설명 1
함수 호출에 성공한 경우이다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
WinTmaxEnd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPETIME]
임계 영역으로 들어갈 수 없는 경우에 발생한다. 시스템 내부 오류로서 시스템 상태를 확인한다.
[TPEPROTO]
tpend()가 부적절한 상황에서 호출되었다. 예를 들어, 호출자가 서버이다. 또는 연결이 해제된 후에 다시 호출된 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
관련함수
tpend(), WinTmaxStart()
13.5. WinTmaxSetContext
Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 Windows 핸들과 메시지 타입을 설정한다.
멀티 Windows 환경에서 사용되며 지정된 Windows 핸들과 메시지 타입을 라이브러리의 빈 slot에 저장하여 관리하도록 한다. 이렇게 관리되는 정보는 작업 Thread가 응답을 수신한 후 지정되어 있는 Windows에게 지정된 메시지 타입으로 데이터를 전송하게 된다. 다음은 데이터 전송 포맷이다.
SendMessage(winhandle, msgType, (UINT) &msg, callRet)
응답을 받게되면 작업 Thread는 SendMessage(winhandle, msgType, (UINT) &msg, callRet)로 데이터를 전송한다. 이 경우 지정된 Windows에서는 WPARAM에는 msg가 대응되며 LPARAM에는 callRet가 대응된다. msg는 TPSVCINFO 구조체이며 callRet는 서비스 처리 결과값으로서 적절한 메시지가 수신된 경우에는 0이며 잘못된 메시지가 수신된 경우에는 –1이다.
예를 들어 정상적으로 tpreturn(TPSUCCESS, …)으로 서비스가 처리되거나 또는 실패한 경우로서 tpreturn(TPFAIL, …)으로 처리되거나 또는 비요청 메시지가 수신된 경우에는 적절한 메시지로 간주하고 callRet 값은 0이 된다. 하지만 동기형 결과값이나 대화형 메시지가 전달되는 경우 이는 멀티 Windows 환경에서 사용할 수 없는 형태이기 때문에 callRet 값은 –1이 된다. callRet 값이 -1일 경우 tperrno 값을 확인하여 오류의 원인을 파악할 수 있다.
-
프로토타입
# include <WinTmax.h> int WinTmaxSetContext(void *winhandle, unsigned int msgType, int slot)
-
파라미터
파라미터 설명 winhandle
수신 데이터를 처리할 Windows 핸들이다.
msgType
메시지 타입이다.
slot
지정된 Windows 핸들과 메시지 타입을 할당할 slot을 의미한다. 할당 가능한 slot의 최대 개수는 256이며 시스템 내부적으로 0과 1은 각각 기본 출력과 에러를 위한 것으로 설정된다. 데이터 수신 과정에서 에러가 발생한다든가 출력용 Windows가 지정되어 있지 않은 경우에는 기본 Windows가 사용된다.
slot은 사용자에 의해서 재정의되어 사용될 수 있다. 비요청 메시지의 경우 사용자가 지정한 윈도우가 없기 때문에 0번 기본 출력 윈도우로 메시지가 전달된다.
다음은 slot에 설정할 수 있는 값이다.
-
–1 : 시스템 내부적으로 비어있는 slot을 자동으로 검색하여 지정된 Windows 핸들과 메시지 타입을 할당한다.
-
0 이상의 값 : 주어진 index의 slot에 지정된 Windows와 메시지 타입을 할당한다.
-
-
반환값
반환값 설명 index
함수 호출에 성공한 경우이다. slot에 대한 index를 반환하고 index는 WinTmaxSend()에서 첫 번째 파라미터로 사용된다.
-1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류WinTmaxSetContext()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
... int CTMaxGwView::Connect() { CString szTemp, Fname; WinTmaxEnd(); int Ret = tmaxreadenv(TMAXINI, “TMAX117”); if(Ret<0) { szTemp.Format(“tmaxreadenv error”); LogDisplay2(2, (char *)(const char *)szTemp, szTemp.GetLength()); return FALSE; } if (WinTmaxStart((TPSTART_T *)NULL) == -1) { szTemp.Format(“WinTmaxStart 에러 = [%s]”, tpstrerror(tperrno)); LogDisplay2(2, (char *)(const char *)szTemp, szTemp.GetLength()); return FALSE; } WinTmaxSetContext(m_hWnd, WM_TMAX_RECV_RDP, 0); WinTmaxSetContext(m_hWnd, WM_TMAX_RECV_ERR, 1); WinTmaxSetContext(m_hWnd, WM_TMAX_RECV, 2); return TRUE; }
-
관련함수
WinTmaxStart(),WinTmaxEnd(), WinTmaxSend()
13.6. WinTmaxSend
Windows 시스템 환경에서 클라이언트에서 사용되는 함수로 데이터를 송신한다. 멀티 Windows 환경에서 사용되며 서비스를 요청하는 함수이다.
-
프로토타입
# include <WinTmax.h> int WinTmaxSend(int recvContext, char *svc, char *data, long len, long flags)
-
파라미터
파라미터 설명 recvContext
Tmax 시스템으로부터 응답을 수신하는 경우에 수신 대상 Windows를 지정한다. WinTmaxSetContext()의 반환값이다.
svc
서비스명이다.
data
tpalloc()으로 할당된 버퍼로 서비스 요청할 때에 전달할 데이터가 저장된다.
len
데이터의 길이 값으로 CARRAY 버퍼 또는 다중 구조체 버퍼를 사용하는 경우에는 정확한 길이 값을 명시해야 한다.
flags
WinTmaxSend()에서 사용할 수 있는 flags 값은 표 이후에 설명한다.
WinTmaxSend()는 tpacall() 함수와 비슷하게 동작하며, 서비스를 요청하고 응답이 도착할 때까지 기다리지 않고 즉시 반환한다. 이후 응답은 WinTmaxStart()를 호출할 때 생성되었던 Thread에서 처리하여 WinTmaxSetContext()에서 설정된 윈도우로 응답 결과를 알려준다. 따라서 응답을 받기 위한 별도의 API는 제공되지 않는다.
다음은 비어있는 slot 하나를 찾아서 (hwd, 0x300)을 저장하고 index를 반환하는 예이다. WinTmaxSetContext()의 반환값 rc를 WinTmaxSend()의 recvContext 파라미터로 사용하며, WinTmaxSend(rc, svc, data, len, 0) 호출 이후에 응답이 오면 hwd windows에 0 x 300번 메시지 및 응답 결과를 전송한다.
rc = WinTmaxSetContext(hwd, 0x300, -1); int nSendResult = WindTmaxSend(rc, (LPSTR)(LPCSTR)strService, (Char*)tpbuf, nLen, TPNOFLAGS); /* 이후 내부 Thread에서 응답 메시지를 처리하여 해당 윈도우로 다음과 같이 메시지를 전달한다. SendMessage(hwd, 0x300, (UINT) &msg, callRet); */
메시지를 받은 윈도우에서는 WPARAM에 응답 데이터(msg), LPARAM에 응답 결과(callRet)를 전달받는다. callRet가 0일 경우 정상적인 응답이고, -1일 경우 오류가 발생했음을 알려준다. 이때 tperrno 값을 통해 오류의 원인을 파악할 수 있다.
WinTmaxSend()는 구조상 트랜잭션을 지원하지 않으며, Tmax 시스템의 환경설정 BLOCKTIME 항목 또는 tpsettimeout()의 영향을 받지 않는다. 다만 WinTmaxSend() 호출할 때 TPBLOCK flag를 주었을 경우에만 해당 flag의 동작 방식에 대해서 BLOCKTIME이 적용된다.
WinTmaxSend()에서 사용할 수 있는 flags 값은 다음과 같다.
flags 값 설명 TPBLOCK
TPBLOCK flags 없이 WinTmaxSend() 함수가 사용되었다면 svc가 등록되어 있지 않거나 서비스 수행에 실패해도 정상적인 결과가 반환된다. 에러는 응답을 받는 시점에 확인할 수 있다.
TPBLOCK flags를 이용하면 서비스 호출 시점에 정상 여부를 확인할 수 있다. 즉, WinTmaxSend()는 BLOCKTIME 이내에 요청한 서비스가 정상적으로 수행가능한지 여부를 확인하고 리턴한다. 만약 요청한 서비스가 수행 불가능할 경우 이에 대한 오류를 tperrno에 저장하고 -1을 리턴한다.
만약 BLOCKTIME 이내에 서비스 수행 여부에 대한 확인이 불가능할 경우 TPETIME 오류를 반환한다. 이 경우 클라이언트에서는 요청한 서비스가 수행되었는지 여부를 알 수 없으므로 에러 루틴을 작성할 때 주의해야 한다. 만약 재요청 처리를 해야 할 경우 기존의 요청이 처리되었는지 여부를 확인하는 방법으로 주의 깊게 처리해야 한다.
TPNOREPLY
WinTmaxSend()로 송신한 서비스 요청은 응답을 기다리지 않고 즉시 반환한다. 결과는 작업 Thread에 의해서 수신되어 등록된 Windows에 전달된다. 그러나 TPNOREPLY flags는 서비스에 대한 응답을 받지 않겠다고 설정하는 것이다.
TPNOTRAN
WinTmaxSend() 함수 호출자가 트랜잭션 모드 상태에서 flags를 설정하여 svc 서비스를 요청했다면 svc 서비스는 트랜잭션 모드에서 제외되어 수행된다.
트랜잭션 모드에서 svc가 트랜잭션을 지원하지 않는 서비스라면 WinTmaxSend() 함수가 트랜잭션 모드에서 호출되는 경우 flags는 반드시 TPNOTRAN으로 설정해야 한다. 트랜잭션 모드 내에서의 WinTmaxSend() 함수를 호출하는 경우 TPNOTRAN로 설정되었어도 여전히 트랜잭션 타임아웃(timeout)에 영향을 받는다. TPNOTRAN으로 호출된 서비스가 실패했을 경우 호출자의 트랜잭션에는 영향을 미치지 않는다.
TPNOBLOCK
TPNOBLOCK flags가 설정한 상태에서, 내부 버퍼가 송신할 메시지들로 가득 찬 경우와 같은 블로킹(blocking) 상황을 만나면 서비스 요청은 실패한다. TPNOBLOCK flags 설정 없이 WinTmaxSend()를 호출하는 경우 블로킹 상황이 발생하면 함수 호출자는 블로킹 상황이 풀리거나 타임아웃(트랜잭션 타임아웃 또는 블록 타임아웃)이 발생할 때까지 기다리게 된다.
TPNOTIME
함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기다리겠다는 것을 의미한다. 그러나 트랜잭션 타임아웃 내에서 WinTmaxSend()을 한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.
TPSIGRSTRT
시그널(signal) 인터럽트를 수용하고자 할 때 사용한다. 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. flags가 설정되지 않은 상태에서 시그널 인터럽트가 발생했다면 함수는 실패하고 tperrno에 TPGOTSIG가 설정된다.
-
반환값
반환값 설명 구별자(descriptor)
함수 호출에 성공한 경우이다. 구별자(descriptor)를 반환한다. 현재 이 구분자는 사용되지 않는다.
-1
함수 호출이 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
WinTmaxSend()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPENOENT]
svc라는 서비스가 존재하지 않아서 서비스를 요청할 수 없다.
[TPEITYPE]
data의 유형 및 하위 유형이 svc가 지원하지 않는 유형이다. 구조체인 경우 사용된 구조체가 SDLFILE 파일에 선언되어 있지 않다.
[TPELIMIT]
처리되지 않은 비동기성 서비스 요청 수가 최대 한계에 도달했기 때문에, 호출자의 서비스 요청이 송신되지 않았다.
[TPETIME]
타임아웃이 발생한 경우로 TPNOTIME이나 TPNOBLOCK이 모두 설정되지 않은 상황에서 블록 타임아웃이 발생한다.
[TPEBLOCK]
TPNOBLOCK이 설정된 상태에서 블로킹 상황이 발생하였다.
[TPGOTSIG]
TPSIGRSTRT가 설정되지 않은 상태에서 시그널이 수신되었다.
[TPEPROTO]
트랜잭션 모드에서 TPNOREPLY 서비스가 호출될 경우 TPNOTRAN flags를 설정하지 않는 경우 등 부적절한 상황에서 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPECLOSE]
네트워크 문제나 기타 여러 가지 원인으로 인해 Tmax 시스템과의 연결이 해제되었다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
Windows로 전달된 메시지의 LPARAM이 -1인 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEBADDESC]
응답 메시지를 수신했으나 올바른 구별자(descriptor)를 찾을 수 없는 경우에 발생한다.
[TPEOTYPE]
응답 메시지를 수신했으나 클라이언트와 서버 프로그램의 버퍼 타입이 일치하지 않는 경우에 발생한다.
[TPEPROTO]
WinTmaxStart(), WinTmaxEnd() 등을 부적절한 상황에서 호출할 경우에 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다.
[TPECLOSE]
네트워크 문제나 기타 여러 가지 원인으로 Tmax 시스템과의 연결이 해제되었다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제
... int CTMaxGwView::SendData2(char *data, long nLen) { CString szTemp; m_send_length.Format(“%d”,nLen); UpdateData(FALSE); char *tpbuf = tpalloc(“STRING”, NULL, nLen); if (tpbuf == NULL) { szTemp.Format(“tpalloc Error [%s]”, tpstrerror(tperrno)); LogDisplay2(2, (char *)(const char *)szTemp, szTemp.GetLength()); return -1; } memcpy(tpbuf, data, nLen); CString strService; strService.Format(“TOUPPER_STRING”); int nSendResult=WinTmaxSend(2,(LPSTR)(LPCSTR)strService, (char*)tpbuf, nLen, 0); tpfree(tpbuf); … }
-
관련 함수
WinTmaxStart(),WinTmaxEnd()
14. MultiThread/MultiContext
MultiThread/MultiContext에 관련된 함수를 설명한다. MultiThread/MultiContext 서버 라이브러리와 클라이언트 라이브러리는 MultiContext 방식에 차이가 있다.
14.1. tpgetctxt
함수를 호출하는 Thread에 현재 설정되어 있는 컨텍스트의 ID를 첫 번째 파라미터로 반환하는 함수이다.
MultiThread/MultiContext 서버에서는 Thread에 설정된 컨텍스트가 유효할 경우 1 이상의 값을 가져오게 되며, 컨텍스트가 설정되어 있지 않거나 유효하지 않을 경우에는 TPNULLCONTEXT(-2)를 가져오게 된다. 컨텍스트는 서비스 Thread에서 서비스 요청을 수행 중인 경우에만 유효하다. 만일 서비스 요청을 모두 처리하고 tpreturn()이 호출되면 해당 컨텍스트는 더 이상 유효하지 않으며, 사용자 생성 Thread에서는 컨텍스트를 더 이상 사용할 수 없다.
tpgetctxt 함수는 클라이언트와 서버 프로그램에서 작성 방법에 차이가 있으므로 아래의 서버와 클라이언트 예제를 구분하여 설명한다.
MultiThread/MultiContext 서버에서는 Singlecontext를 지원하지 않는다. |
-
프로토타입
#include <usrinc/atmi.h> int tpgetctxt(int *ctxtid, long flags)
-
파라미터
파라미터 설명 ctxtid
함수를 호출한 시점의 현재 컨텍스트를 얻어온다.
-
multicontext 인 경우: 1보다 큰 값을 가져온다.
-
singlecontext인 경우: 0값을 가져온다.
flags
현재 버전에서는 지원하지 않으나 TPNOFLAGS로 설정한다.
-
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpgetctxt()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEINVAL]
잘못된 파라미터가 설정되었다. 예를 들어 첫 번째 파라미터가 포인터 값이던가, 두 번째 파라미터가 0이 아닌 값으로 설정된 경우 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제 - 클라이언트 프로그램
int newContext() { int i; int id; i = tpstart(tpinfo); if (i < 0) { printf(“\t[newContext]tpstart fail[%d][%s]\n",tperrno,tpstrerror(tperrno)); tpfree((char *)tpinfo); return -1; } i = tpgetctxt(&id,TPNOFLAGS); if (i < 0) { printf("\t[newContext]tpgetctxt fail[%d][%s]\n",tperrno,tpstrerror(tperrno)); return -1; } return id; }
-
예제 - 서버 프로그램
typedef param { int ctxtid; TPSVCINFO *svcinfo; } param_t; MSERVICE(TPSVCINFO *svcinfo) { pthread_t tid; param_t param; printf("MSERVICE service is started!"); tpgetctxt(¶m.ctxtid, TPNOFLAGS); param.svcinfo = svcinfo; pthread_create(&tid, NULL, THREAD_ROUTINE, ¶m); pthread_join(tid, NULL); printf("MSERVICE service is finished!"); tpreturn(TPSUCCESS, 0, svcinfo->data, 0L, TPNOFLAGS); } void *THREAD_ROUTINE(void *arg) { param_t *param; TPSVCINFO *svcinfo; param = (param_t *)arg; svcinfo = param->svcinfo; if (tpsetctxt(param->ctxtid, TPNOFLAGS) == -1) { printf("tpsetctxt(%d) failed, [tperrno:%d]", param->ctxtid, tperrno); return NULL; } tpcall("MTOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, TPNOFLAGS); if (tpsetctxt(TPNULLCONTEXT, TPNOFLAGS) == -1) { printf("tpsetctxt(TPNULLCONTEXT) failed, [tperrno:%d]", tperrno); return NULL; } return NULL; }
-
관련함수
tpsetctxt()
14.2. tpsetctxt
현재 컨텍스트를 설정하는 함수로 클라이언트 프로그램과 서버 프로그램에서 다음과 같은 작성 방법의 차이가 있다.
-
클라이언트 프로그램
함수를 사용하여 하나의 클라이언트가 기존에 생성된 다른 context를 현재 클라이언트에 할당할 수 있고 대부분의 ATMI 함수들은 per-context 기반으로 되어 있다. 클라이언트의 현재 context를 알기 위해서는 tpgetctxt()라는 함수를 사용하여 반환되는 값으로 확인할 수 있다.
클라이언트는 여러 개의 context를 사용할 수 있지만 해당하는 순간에는 단 하나의 context만을 갖게 된다. 예를 들면 context1에서 tpacall()을 한 경우 다른 context를 사용했다 하더라도 tpgetrply()를 정상적으로 하기 위해서는 tpgetrply()를 하는 시점에서는 context1을 현재 context로 설정해 주어야 한다.
-
서버 프로그램
서비스 Thread는 서비스를 처리할 때 context를 할당받아서 사용하게 되지만, 사용자 생성 Thread는 자신만의 context가 존재하지 않는다. 대부분의 ATMI 함수들은 context가 할당되어야만 동작할 수 있다. 따라서 사용자 생성 Thread는 필요한 경우에는 서비스 Thread의 context를 공유해서 사용해야 한다. 사용자 생성 Thread는 tpsetctxt 함수를 사용하여 다른 서비스 Thread의 context를 공유할 수 있다.
tpsetctxt를 호출한 사용자 생성 Thread는 서비스 Thread와 context 정보를 공유한다. 예를 들어 서비스 Thread에서 tpacall()을 호출하면 그 이후 사용자 생성 Thread에서 tpgetrply()를 통해 요청에 대한 응답을 받는 것이 가능하다.
tpsetctxt() 함수는 서비스 Thread에서는 사용할 수 없다. 서비스 Thread는 기본적으로 자신의 context를 가지고 있으며, 다른 context로 교체하여 사용할 수 없다. 따라서 서비스 Thread에서 tpsetctxt() 함수를 호출하면 TPEPROTO 에러 코드와 함께 에러를 반환하게 된다.
사용자 생성 Thread에서 이 함수를 통해 서비스 Thread의 context를 공유한 경우에는 반드시 서비스 Thread가 tpreturn()을 호출하기 전에 먼저 사용자 생성 Thread에서 tpsetctxt(TPNULLCONTEXT)를 호출해야 한다. 즉, 서비스 Thread가 tpreturn()을 호출하는 시점에 다른 사용자 생성 Thread가 서비스 Thread의 context를 공유하지 않도록 변경해야 한다. 이를 지키지 않으면 tpreturn()은 실패하게 되고 클라이언트로 TPESVCERR 에러 코드를 반환하게 된다. 따라서 반드시 동기화 등을 통해 이들 Thread 사이에서의 프로세스 흐름을 제어해야 한다. tpsetctxt() 함수의 ctxtid 파라미터는 서비스 Thread에서 tpgetctxt() 함수를 호출해서 얻은 Context-ID를 사용한다.
프로그램에 따라 작성 방법에 다른 것에 유의하고, tpsetctxt() 함수의 기본적인 정보는 다음과 같다.
-
프로토타입
#include <usrinc/atmi.h> int tpsetctxt(int ctxtid, long flags)
-
파라미터
파라미터 설명 ctxtid
함수를 호출한 시점의 현재 컨텍스트를 설정한다. 설정 가능한 컨텍스트는 클라이언트 프로그램에서는 tpstart()를 사용하여 새로운 컨텍스트가 생성된 ID이고, 서버 프로그램에서는 서비스 Thread의 Context-ID이다.
TPNULLCONTEXT를 비롯한 다른 사용 가능한 컨텍스트로 설정할 수 있으나 TPINVALIDCONTEXT로는 설정할 수 없다.
flags
현재 버전에서는 지원하지 않으나 TPNOFLAGS이나 0으로 설정한다.
-
반환값
반환값 설명 -1
함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
-
오류
tpsetctxt()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.
에러 코드 설명 [TPEPROTO]
서버 프로그램의 경우에 서비스 Thread에서 호출한 경우이거나 파라미터로 전달된 Context ID가 유효하지 않는 값인 경우 등 부적절한 상황에서 함수를 호출한 경우 발생한다.
[TPEINVAL]
잘못된 파라미터가 설정된 경우로 ctxtid에 0 또는 TPINVALIDCONTEXT가 설정된 경우나 flags 값에 0 이외의 값이 설정된 경우이다.
클라이언트 프로그램에서는 tpstart()를 수행하기 전에 이 함수를 호출한 경우 발생한 경우로 tpstart()를 호출할 때 버퍼의 flags를 TPMULTICONTEXTS로 설정하지 않은 상태에서 이 함수를 호출한 경우 발생한다.
ctxtid가 TPINVALIDCONTEXT이거나 0으로 설정된 경우에 발생한다.
[TPENOENT]
ctxtid에 설정된 값이 설정 가능한 컨텍스트가 아닌 경우 발생한다.
[TPESYSTEM]
Tmax 시스템에 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
[TPEOS]
운영 시스템에 에러가 발생하였다.
-
예제 - 클라이언트 프로그램
int altContext(int id) { int i; int ret; ret = tpsetctxt(id, TPNOFLAGS); if (ret < 0) { printf(“\t[altContext]tpsetctxt fail[%d][%s]\n"tperrno, tpstrerror(tperrno)); tpfree((char *)tpinfo); return -1; } return 1; }
-
예제 - 서버 프로그램
typedef param { int ctxtid; TPSVCINFO *svcinfo; } param_t; MSERVICE(TPSVCINFO *svcinfo) { pthread_t tid; param_t param; printf("MSERVICE service is started!"); tpgetctxt(¶m.ctxtid, TPNOFLAGS); param.svcinfo = svcinfo; pthread_create(&tid, NULL, THREAD_ROUTINE, ¶m); pthread_join(tid, NULL); printf("MSERVICE service is finished!"); tpreturn(TPSUCCESS, 0, svcinfo->data, 0L, TPNOFLAGS); } void *THREAD_ROUTINE(void *arg) { param_t *param; TPSVCINFO *svcinfo; param = (param_t *)arg; svcinfo = param->svcinfo; if (tpsetctxt(param->ctxtid, TPNOFLAGS) == -1) { printf("tpsetctxt(%d) failed, [tperrno:%d]", param->ctxtid, tperrno); return NULL; } tpcall("MTOUPPER", sndbuf, 0, &rcvbuf, &rcvlen, TPNOFLAGS); if (tpsetctxt(TPNULLCONTEXT, TPNOFLAGS) == -1) { printf("tpsetctxt(TPNULLCONTEXT) failed, [tperrno:%d]", tperrno); return NULL; } return NULL; }
-
관련함수
tpgetctxt()