제3장 UCS 함수

내용 목차

3.1. 개요
3.2. 서버/클라이언트 함수
3.2.1. tppost
3.2.2. tpsetfd
3.2.3. tpsubscribe
3.2.4. tpunsubscribe
3.3. 서버 함수
3.3.1. tpclrfd
3.3.2. tpissetfd
3.3.3. tpregcb
3.3.4. tprelay
3.3.5. tpsavectx
3.3.6. tpschedule
3.3.7. tpsendtocli
3.3.8. tpsvctimeout
3.3.9. tpsvrdone
3.3.10. tpsvrdown
3.3.11. tpunregcb
3.4. 클라이언트 함수
3.4.1. tpgetunsol
3.4.2. tpsetunsol
3.4.3. tpsetunsol_flag

본 장은 UCS에서 사용하는 함수에 대해 기술한다.

다음은 UCS 프로그램에서 사용하는 함수의 종류이다.

  • 서버/클라이언트 함수

    함수설명
    tppost특정 사건을 발생시키고 메시지를 전달한다.
    tpsetfd소켓 fd를 UCS 프로세스의 스케줄러에 등록한다.
    tpsubscribe특정 사건의 메시지에 대한 요청을 등록한다.
    tpunsubscribe특정 사건의 메시지에 대한 등록을 해제한다.
  • 서버 함수

    함수설명
    tpclrfd프로세스 내부의 fdset의 소켓 fd를 off시킨다.
    tpissetfd소켓 fd로 데이터가 도착했는지를 검사한다.
    tpregcb비동기형 요청에 대한 응답을 받는 루틴을 설정한다.
    tprelay서버 프로세스에서 서비스를 요청한 클라이언트의 정보를 담아서 또 다른 서비스를 요청한다.
    tpsavectx서버 프로세스에서 클라이언트의 정보를 내부적으로 관리한다.
    tpschedule서버 프로세스에서 데이터의 도착을 기다린다.
    tpsendtocli지정된 클라이언트에 비요청 메시지를 송신한다.
    tpsvctimeout서비스 타임아웃이 발생했을 경우에 호출한다.
    tpsvrdown서버 프로세스를 종료한다.
    tpunregb비동기형 요청에 대한 응답을 받는 루틴을 재설정한다.
  • 클라이언트 함수

    함수설명
    tpgetunsol비요청 메시지 수신한다.
    tpsetunsol수신한 비요청 메시지를 처리하는 루틴을 설정한다.
    tpsetunsol_flag비요청 메시지의 수신 flags를 변경한다.

서버와 클라이언트에서 특정 사건을 발생시키고 메시지를 전달하는 함수이다. tppost()는 이름이 eventname인 사건에 tpsubscribe()로 등록된 모든 클라이언트와 서버 프로세스에게 사건의 발생을 알리고 필요할 경우 메시지를 전달한다.

  • 프로토타입

    # include <tmaxapi.h>
    int tppost(char *eventname, char *data, long len, long flags)
  • 파라미터

    파라미터설명
    eventnameNULL로 끝나는 15자 이내의 문자열로 발생할 사건의 이름을 의미한다. 와일드카드 문자나 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()

소켓 fd를 UCS 프로세스의 외부 소켓 스케줄러에 등록하는 함수로 UCS 방식 프로세스를 사용한 소켓 fd를 켤 때 사용된다. UCS 스케줄러는 TMM, CLH 뿐만 아니라 해당 소켓 fd에 도착한 메시지도 같이 검사한다. 사용자가 지정한 소켓에 메시지가 도착했을 경우 tpschedule()은 별도의 처리없이 정상 결과(UCS_USER_MSG)를 반환하며 어떤 소켓에 메시지가 도착했는지를 알기 위해서는 아래에 설명된 tpisetfd()를 사용해야 한다.

  • 프로토타입

    #include <ucs.h>
    int  tpsetfd (int  fd)
  • 파라미터

    파라미터설명
    fd등록할 소켓 fd를 설정한다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
  • 오류

    tpsetfd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPESYSTEM]Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
    [TPEOS]운영 시스템에 에러가 발생하였다.
  • 예제

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ... 
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
     
    int fd_read(int, char *, int);
    extern int errno;
     
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){
            error processing
        }
     
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){
            error processing
        }
     
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
     
        if (inaddr != -1){
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
        } 
        ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
        if (ret == -1){
            error processing
        }
        ret = listen(listen_fd, 5);
        if (ret == -1){
            error processing
        }
     
        ret = tpsetfd(listen_fd);
        if (ret == -1){
            error processing
        }
        ...
    
        while(1) {
            n = tpschedule(10);
            ...
            if (n == UCS_USER_MSG){
                if (tpissetfd(listen_fd)) {
                    child_len = sizeof(child_addr);
                    newfd = accept(listen_fd, &child_addr, &child_len);
                    if (newfd == -1){
                        error processing
                    }
     
                ret = tpsetfd(newfd);
                if (ret == -1){
                    error processing
                }
            }
     
            if (tpissetfd(newfd)){
                /* 소켓으로 부터 버퍼를 읽는다 */
                fd_read(newfd, buf, 1024);
                ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf, 
                               (long *)&rlen, TPNOFLAGS);
                if (ret == -1){
                    error processing
                }
                ...
                tpclrfd(newfd);
                close(newfd);
            }
            ...   
        }
        return 1;
    } 
  • 관련 함수

    tpclrfd(), tpissetfd()

서버와 클라이언트에서 사용되는 함수로, 특정 사건의 발생시점에 클라이언트나 서버로부터 데이터를 전달받기 위한 요청을 등록한다. eventname에 해당하는 사건이 발생하면 알려 달라는 것을 Tmax 시스템에 등록하는 함수이다.

  • 프로토타입

    # include <tmaxapi.h>
    long tpsubscribe(char *eventname, char *filter, TPEVCTL *ctl, long flags)
  • 파라미터

    파라미터설명
    eventnameNULL로 끝나는 15자 이내의 문자열로 메시지를 받을 사건의 이름을 지정한다. 와일드카드 문자나 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으로 채워야한다.
    qnameqname을 사용할 경우 메시지는 tpenq(qname, NULL, data, len, TPNOFLAGS)를 통해 RQ에 저장된다.
    svcsvc를 사용할 경우 메시지는 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()

UCS 방식 프로세스 내부의 fdset의 소켓 fd를 off시키는 데 사용되는 함수로, UCS 방식 서버 프로세스의 외부 소켓을 스케줄링하는 경우에 사용한다.

  • 프로토타입

    #include <ucs.h>
    int  tpclrfd (int fd)
  • 파라미터

    파라미터설명
    fdoff할 내부 fdset의 소켓이다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
  • 오류

    tpclrfd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPESYSTEM]Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
    [TPEOS]운영 시스템에 에러가 발생하였다.
  • 예제

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ….
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){ error processing }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){ error processing }
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
        if (inaddr != -1){
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
        }
    
        ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
        if (ret == -1){ error processing }
        ret = listen(listen_fd, 5);
        if (ret == -1){ error processing }
    
        tpsetfd(listen_fd);
        ...
        while(1) {
            n = tpschedule(10);
            ...
            if (n == UCS_USER_MSG){
            if (tpissetfd(listen_fd)) {
                child_len = sizeof(child_addr);
                newfd = accept(listen_fd, &child_addr, &child_len);
                if (newfd == -1){ error processing }
                tpsetfd(newfd);
            }
    
            if (tpissetfd(newfd)){
                /* 소켓으로 부터 버퍼를 읽는다 */
                fd_read(newfd, buf, 1024);
                ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf, 
                             (long *)&rlen, TPNOFLAGS);
                if (ret == -1){ error processing }
                    ...
                ret = tpclrfd(newfd);
                if (ret == -1){ error processing }
                close(newfd);
            }
            ...
       }
       return 1;
    }
  • 관련 함수

    tpissetfd()

서버에서 UCS 프로세스에서 소켓 fd로 데이터가 도착했는지를 검사하는 함수로, UCS 방식 서버 프로세스의 외부 소켓을 스케줄링하는 데 사용한다.

  • 프로토타입

    #include <ucs.h>
    int  tpissetfd (int fd)
  • 파라미터

    파라미터설명
    fd테스트할 fdset 내부의 fd를 설정한다.
  • 반환값

    반환값설명
    양수메시지가 도착했을 경우이다.
    0메시지가 도착하지 않은 경우이다.
    -1함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
  • 오류

    tpissetfd()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPESYSTEM]Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
    [TPEOS]운영 시스템에 에러가 발생하였다.
  • 예제

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <usrinc/ucs.h>
    ...
    
    #define SERV_ADDR “168.126.185.129”
    #define SERV_PORT 1500
    
    int fd_read(int, char *, int);
    extern int errno;
    
    int usermain(int argc, char *argv[])
    {
        ...
        int listen_fd, n, newfd;
        struct sockaddr_in my_addr, child_addr;
        socklen_t child_len;
    
        buf = tpalloc(“STRING”, NULL, 0);
        if (buf == NULL){ error processing }
    
        memset((void *)&my_addr, NULL, sizeof(my_addr));
        memset((void *)&child_addr, NULL, sizeof(child_addr));
    
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (listen_fd == -1){ error processing }
    
        my_addr.sin_family = AF_INET;
        inaddr = inet_addr(SERV_ADDR);
        my_addr.sin_port = htons((unsigned short)SERV_PORT);
        if (inaddr != -1)
            memcpy((char *)&my_addr.sin_addr, (char *)&inaddr, sizeof(inaddr));
    
            ret = bind(listen_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
            if (ret == -1){ error processing }
            ret = listen(listen_fd, 5);
            if (ret == -1){ error processing }
    
            tpsetfd(listen_fd);
            ...
            while(1) {
                n = tpschedule(10);
                ...
                if (n == UCS_USER_MSG){
                    if (tpissetfd(listen_fd)) {
                        child_len = sizeof(child_addr);
                        newfd = accept(listen_fd, &child_addr, &child_len);
                        if (newfd == -1){ error processing }
                        tpsetfd(newfd);
                }
                if (tpissetfd(newfd)){
                    /* 소켓으로부터 버퍼를 읽는다 */
                    fd_read(newfd, buf, 1024);
                    ret = tpcall(“SERVICE”, (char *)buf, sizeof(buf), (char **)&buf, 
                                  (long *)&rlen, TPNOFLAGS);
                    if (ret == -1){ error processing }
                    ...
                    tpclrfd(newfd);
                    close(newfd);
                }
            ...
            }
        } 
        return 1;
    }
  • 관련함수

    tpissetfd(), tpsetfd()

서버에서 UCS의 비동기형 요청에 대한 응답을 받는 루틴을 설정하는 함수로, UCS 방식 프로세스가 서버 프로그램으로부터 응답을 받았을 때 이를 처리할 루틴을 설정한다. UCS 방식 서버 프로세스에 tpgetreply() 대신 사용된다.

  • 프로토타입

    # include <ucs.h>
    int  tpregcb (UcsCallback)
  • 파라미터

    파라미터설명
    UcsCallbackUCS에서 비동기형 요청에 대한 응답을 처리하는 Callback 함수를 지정한다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
  • 오류

    tpregcb()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPESYSTEM]Tmax 시스템 에러가 발생하였다. 자세한 정보는 로그 파일에 기록된다.
    [TPEOS]운영 시스템에 에러가 발생하였다.
  • 예제

    ...
    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    
    void reply_receive(UCSMSGINFO *reply);
    DUMMY(TPSVCINFO *msg)
    {
        data process ….
    }
    
    int usermain(int argc, char *argv[])
    {
        int ret;
        char *buf
    
        ret = tpregcb(reply_receive);
        if (ret == -1){ error processing }
        buf=tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        data process…
        while(1)
        {
            ...
            tpschedule(3);
            cd = tpacall(“SERVICE”, buf, strlen(buf), TPNOFLAGS);
            if (cd < 0) { error processing }
            ...
        }
    }
    
    void reply_receive(UCSMSGINFO *reply)
    {
        rtcd = reply->errcode;
    
        if(rtcd != 0)
        {
             printf("[tperrno(%d) : %s]\n", rtcd,tpstrerror(rtcd));
             /* 에러 처리 코드 */
        }
    
        printf(“data....%s\n”, reply->data);
    }
  • 관련 함수

    tpunregcb()

UCS 형태의 서버 프로세스에서만 사용 가능한 함수로, 서비스를 요청한 클라이언트에 대한 정보를 담아서 또 다른 서비스를 요청하는 방식으로 멀티 노드 간에도 서비스가 이루어진다. 이런 형식을 취하면 tprelay()를 통해서 호출된 서비스는 마치 클라이언트가 자기를 직접 호출한 것으로 인식하고 서비스의 수행 결과는 최초 서비스를 요청한 클라이언트에게 전달된다.

서비스 수행 결과를 호출한 클라이언트에게 전달할 수 있으므로 UCS 프로세스에서 간단한 구성을 통해 빠른 응답을 유도할 수 있다. 대체적으로 2~3번의 서비스를 호출해야만 결과를 얻어낼 수 있는 프로그램 루틴인 대외기간 업무와 연동하여 서비스를 처리하는 경우에 사용하는 것이 좋다.

만약 tpsavcctx() 또는 tpgetctx()를 통해 클라이언트 정보를 저장한 이후에 tprelay()를 통해 다른 서비스를 요청하지 않은 상태에서 서버 프로세스가 종료되는 경우에는 자동으로 서비스 호출자에게 에러 응답이 전달된다. 에러 응답의 전달과 관련해서는 환경설정 SERVER 절의 CTX_EREPLY 옵션을 참고한다. 이러한 동작은 Tmax v5.0 SP2 이후 버전에서부터 지원되며, 이전 버전에서는 이와 같은 상황에서 서비스 호출자에게 에러 응답이 전달되지 않았다.

  • 프로토타입

    #include <ucs.h>
    int  tprelay(char *svc, char *data, long len, long flags, CTX_T *ctxp);
  • 파라미터

    파라미터설명
    svcTmax 환경 파일에 등록된 서비스명을 지정한다.
    data서비스를 호출할 때 전달되는 데이터로 NULL이 아닌 경우는 반드시 tpalloc()으로 할당된 버퍼를 사용해야 한다.
    len보내는 데이터의 길이를 지정한다. CARRAY, X_OCTET, 구조체 배열 타입일 경우에는 반드시 설정해야 한다.
    flags현재 지원하지 않는 파라미터로 TPNOFLAGS를 설정한다.
    ctxptpgetctx() 혹은 tpsavectx()로 받아온 정보 구조체이다.
  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
  • 오류

    tprelay()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPEINVAL]파라미터가 유효하지 않다. 예를 들어 ctxp가 NULL이거나 잘못된 버퍼를 사용한 경우에 발생한다.
    [TPESYSTEM]Tmax 시스템적인 에러가 발생하였다.
  • 예제

    ...
    #include <stdio.h>
    #include <usrinc/ucs.h>
    CTX_T *ctx = NULL;
    
    DUMMY(TPSVCINFO *msg)
    {
        data process ….
    }
    
    usermain(int argc, char *argv[])
    {
        int ret, i;
        char *rcvbuf, *sndbuf;
        long sndlen;
    
        rcvbuf = (char *)tpalloc(“CARRAY”,NULL, 1024);
        if (rcvbuf == NULL){ error processing }
        i = 0;
    
        while(1) {
            tpschedule(1);
            if (ctx != NULL) 
            {
                i++;
                if ((sndbuf = (char *)tpalloc(“CARRAY”,NULL, 1024)) == NULL)
                { error processing }
                else 
                {
                     ...
                     ret = tprelay(“TPRETURN”, sndbuf, sndlen, 0, ctx);
                     if (ret==-1) { error processing }
                     data process...
                     ctx = NULL;
                     tpfree(sndbuf);
                 }
            }
        }
    }
    
    int RELAY(TPSVCINFO *rqst)
    {
       ...
       ctx = tpsavectx();
       tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);
    }
  • 관련 함수

    tpreturn(), tpforward()

UCS 프로세스에서 사용되며 클라이언트의 정보를 내부적으로 관리하도록 한다. tpsavectx()는 tprelay() 함수와 함께 사용된다. tprelay()는 처리 결과를 다른 서비스로 전달하는 역할을 수행한다. 일반적인 서비스 프로그램에서 tpforward 형식으로 다른 서비스를 부른 것과 동일하게 동작한다. 결과적으로 호출된 서비스에서는 처리된 결과값을 해당 클라이언트에게 전달한다.

tpsavectx() 함수는 대외기관 업무와 같이 다른 프로토콜이 이용되며 시간이 많이 소요되어 채널이 묶일 수 있는 가능성이 많은 경우에 사용된다.

일반적으로 사용되는 형태는 다음과 같다.

클라이언트 → svc1 → svc2(service, tpsavectx) → 대외기관
클라이언트 ← svc3 ← svc2(usermain, tprelay) ← 대외기관 
  1. 클라이언트가 svc1에게 원하는 서비스를 요청한다.

  2. svc1에서는 tpforward(...TPNOREPLY)를 이용해서 svc2를 호출한다.

  3. svc2는 UCS 프로세스에 존재하는 서비스이며 서비스 루틴 내에서 tpsavectx()를 사용하여 클라이언트의 정보를 저장하며 대외기관과 통신한다.

  4. 결과는 usermain에서 수신하며 이를 tprelay()를 통해서 svc3에게 전달한다. svc3는 svc2에서 tpforward로 자신을 호출한 것으로 간주하여 최종 결과를 주어진 클라이언트에게 전달한다.

svc1에서 서비스를 TPNOREPLY로 전달하고 있기 때문에 채널이 묶이는 것을 방지할 수 있어 작은 수의 업무 프로세스로도 많은 클라이언트를 감당할 수 있다. 또한 하나의 UCS 프로세스로서 송, 수신 프로세스 역할을 겸함으로써 비교적 단순한 시스템을 구성할 수 있다. 이는 시스템 관리 측면에서도 효율적이다.

  • 프로토타입

    #include <ucs.h>
    CTX_T * tpsavectx(void)
  • 반환값

    반환값설명
    CTX_T함수 호출에 성공한 경우이다.
    NULL함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.

  • 오류

    tpsavectx()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPEPROTO]tpsavectx() 함수는 반드시 서비스 루틴 내에서 사용해야 한다. 서비스 루틴이 아닌 곳에 사용되는 경우에는 TPEPROTO 에러가 발생한다. tpsvrinit() 혹은 tpsvrdone()에서는 사용될 수 없다.
    [TPESYSTEM]메모리 할당 오류가 발생하였다.
  • 예제

    ...
    #include <stdio.h>
    #include <usrinc/ucs.h>
    
    CTX_T *ctx = NULL;
    
    usermain(int argc, char *argv[])
    {
        int ret, i;
        char *rcvbuf, *sndbuf;
        long sndlen;
    
        rcvbuf = (char *)tpalloc(“CARRAY”,NULL, 1024);
        if (rcvbuf == NULL){ error processing }
    
        i = 0;
        while(1) {
            tpschedule(1);
            if (ctx != NULL) 
            {
                i++;
                if ((sndbuf = (char *)tpalloc(“CARRAY”,NULL, 1024)) == NULL)
                { error processing }
                else 
                {
                    ...
                    ret = tprelay(“TPRETURN”, sndbuf, sndlen, 0, ctx);
                    if (ret==-1) { error processing }
                    data process...
                    ctx = NULL;
                    tpfree(sndbuf);
                }
            }
        }
    }
    
    int RELAY(TPSVCINFO *rqst)
    {
        ...
        ctx = tpsavectx();
        tpreturn(TPSUCCESS, 0, rqst->data, rqst->len, 0);
    }
  • 관련 함수

    tpreturn(), tpforward(), tprelay()

UCS 형태의 서버 프로세스에서만 사용 가능한 함수로 UCS 서버 프로세스에서 데이터의 도착을 기다린다. 최대 타임아웃 시간동안 sleep하다가 그 안에 데이터가 도착하면 즉시 반환한다.

tpschedule() 함수는 데이터가 도착했을 때 해당되는 서비스가 자동적으로 수행되고 난 후에 반환된다. 그러므로 데이터가 도착한 후에 사용자가 임의로 서비스를 수행하면 안 된다.

주의

서비스는 무조건 시스템에 의해서 항상 수행되므로 UCS 형태의 서비스 프로그램이라도 이점을 주의해야 한다.

  • 프로토타입

    #include <ucs.h>
    int  tpschedule(int timeout)
  • 파라미터

    파라미터설명
    timeout

    기다리고자 하는 시간을 초 단위로 입력해야 한다.

    • -1: 데이터가 도착했는지 체크만 한 후 즉시 반환한다.

    • 0: 데이터가 도착할 때까지 무한 대기한다.

  • 반환값

    반환값설명
    양의 정수함수가 수행에 성공해서 데이터가 도착한 경우이다.
    -1타임아웃 시간까지 데이터가 도착하지 않은 경우 또는 함수가 수행에 실패해서 에러가 발생한 경우이다. 타임아웃 시간까지 데이터가 도착하지 않으면 -1을 반환하고, tperrno에13번(TPETIME)이 설정된다. 그 외의 경우 tperrno에 에러 코드가 설정된다.
  • 오류

    tpschedule()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPESYSTEM]Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
    [TPEOS]운영 시스템에 에러가 발생하였다.
    [TPETIME]타임아웃 시간까지 데이터가 도착하지 않았다.
    [TPEPROTO]함수가 부적절한 상황에서 호출되었을 경우이다. 예를 들어 서비스 내에서 호출하는 경우 발생한다.
  • 예제

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/ucs.h>
    int usermain(int argc, char *argv[])
    {
        ...
        while(1)
        {
            ...
            tpschedule(3);
            ret = tpcall(“SERVICE”, (char *)buf, strlen(buf), (char **)&buf, 
                          (long *)&rlen, TPNOFLAGS);
            if (ret == -1) { error processing}         
            ...
        }
    }
  • 관련 함수

    tpsleep(), tp_sleep(), tp_usleep()

서버에서 사용되는 함수로 지정된 클라이언트에게 비요청 메시지를 송신한다. tpbroadcast()는 Tmax 시스템에 접속되어 있는 임의의 클라이언트에 비요청 메시지를 전송한다. tpsendtocli()는 서버 프로세스에서 해당 서버 프로세스가 제공하는 서비스를 요청한 클라이언트에게만 비요청 메시지를 보내기 위해 사용한다.

  • 프로토타입

    # include <tmaxapi.h>
    int  tpsendtocli (int  clid,  char  *data,  long  len,  long  flags)
  • 파라미터

    파라미터설명
    clidtpgetclid()로 얻은 클라이언트의 유일한 번호이다.
    datatpalloc()에 의해 할당된 버퍼로 data가 길이를 명시하지 않아도 되는 버퍼로 설정된 경우 len은 무시되고 보통 0이 사용된다. data가 길이를 반드시 명시해야 하는 버퍼로 설정된 경우 len은 0이 될 수 없다. data가 NULL인 경우 len은 무시된다.
    len송신하는 버퍼의 길이이다.
    flags

    TPNOFLAG, TPUDP, TPFLOWCONTROL이 있으며 해당 flags에 따라 동작 방식이 결정된다.

    flags로 사용 가능한 값은 다음과 같다.

    • TPNOFLAG(0)

      메시지는 클라이언트에게 수신되어야 한다. 하지만 클라이언트가 수신된 메시지를 빠르게 처리하지 못한다면 요청한 결과를 수신할 때 오랜 시간이 걸릴 수 있다.

    • TPUDP

      TPUDP flags는 클라이언트와 데이터를 통신하는 방식이 UDP라는 의미가 아니다. 호출자가 데이터를 송신할 때, 송신할 내부 버퍼에 전달될 메시지가 가득 차서 보내지 못할 경우가 있다. 이 경우 데이터는 버려도 된다는 의미이다. 통신의 UDP처럼 데이터가 도중에 분실될 수 있다는 것을 의미이다.

    • TPFLOWCONTROL

      클라이언트의 상태를 점검하고 다른 메시지를 요청할 수 있는지 확인한다. 해당 클라이언트로의 송신 메시지가 너무 많이 쌓여 있다면 tpsendtocli()는 –1을 반환하고 tperrno를 TPEQFULL로 설정한다. 이 flags는 Tmax 시스템의 부하를 줄여준다.

  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다. tperrno에 에러 코드가 설정된다.
  • 오류

    tpsendcli()가 정상적으로 수행되지 않을 경우 tperrno에 다음 값 중 하나가 설정된다.

    에러 코드설명
    [TPEBADDESC]clid가 유효하지 않다.
    [TPEPROTO]tpsendtocli()가 부적절한 상황에서 호출되었다.
    [TPESYSTEM]Tmax 시스템 에러가 발생한 경우로 자세한 정보는 로그 파일에 기록된다.
    [TPEOS]운영 시스템에 에러가 발생하였다.
    [TPEQFULL]송신할 메시지가 있으므로 같은 메시지일 경우에는 재전송할 필요가 없다.

  • 예제

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include <usrinc/tmaxapi.h>
    
    SERVICE(TPSVCINFO *msg)
    {
        int ret, clid;
        char *buf;
     
        buf = (char *)tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        strcpy(buf, msg->data);
        data process….
        clid = tpgetclid();
        if (clid==-1) { error processing }
    
        ret=tpsendtocli(clid, (char *)buf, 0, 0);
        if (ret==-1) { error processing }
        tpreturn(TPSUCCESS, 0, 0, 0);
    }
  • 관련 함수

    tpbroadcast()

UCS 방식 서버 프로세스를 종료하는 함수로, Tmax 응용 서버 프로그램의 분리된 main은 서비스 요청 처리를 모두 마치고 프로세스를 종료하기 전에 tpsvrdone()을 호출한다. 루틴이 실행될 때, 그 서버 프로세스는 여전히 시스템의 일부이기는 하지만 서비스는 지원하지 않는다. tpsvrdone() 루틴 내에서 Tmax 통신이 수행되거나 트랜잭션이 정의될 수도 있다.

tpsvrdone()이 대화형 연결을 유지하고 있는 경우는 Tmax는 대화형 연결을 종료한다. 비동기성 응답을 대기하고 있는 경우는 대기하고 있던 비동기성 응답들을 무시한다. 트랜잭션 모드에 있는 동안은 트랜잭션을 중지하고 서버는 바로 종료된다.

애플리케이션에서 tpsvrdone() 루틴을 제공하지 않는다면 Tmax가 제공하는 기본(default) 루틴이 대신 호출된다. 기본 tpsvrdone()은 트랜잭션을 처리하는 서버 그룹에 포함된 서버이면 tx_close()userlog()를 호출하여 서버가 곧 종료할 것임을 알린다. tpreturn()이나 tpforward() 중 하나가 tpsvrdone() 내에서 호출된다면 이러한 루틴들은 아무런 작동없이 단순히 반환만 한다.

  • 프로토타입

    # include <tmaxapi.h>
    int tpsvrdone(void)
  • 반환값

    tpsvrdone()은 개발자가 서버 프로세스의 종료를 수행하기 전에 필요한 작업을 수행하도록 작성하는 함수로 반환값은 없고 오류도 발생하지 않는다.

  • 예제

    #include <stdio.h>
    #include <usrinc/atmi.h>
    
    EXEC SQL INCLUDE sqlca.h;
    
    SERVICE(TPSVCINFO *msg)
    {
        int ret, cd;
        char *buf;
    
        EXEC SQL begin declare section;
        ….
        EXEC SQL end declare section;
        EXEC SQL CONNECT : scott IDENTIFIED BY : tiger; 
        buf=tpalloc(“STRING”, NULL, 0);
        if (buf==NULL) { error processing }
        data process….
    
        cd=tpgetclid();
        if (cd==-1) { error processing }
        ret=tpsendtocli(cd, buf, 0, TPNOFLAGS);
        if (ret==-1) { error processing }
        data process....
    
        tpreturn(TPSUCCESS,0,buf, strlen(buf), 0);
    }
    
    int tpsvrdone()
    {
        printf(“ Sevice end\n”);
        EXEC SQL COMMIT WORK RELEASE;
    }
  • 관련 함수

    tx_close(), tpsvrinit()

클라이언트의 요청 없이 일방적으로 전달받은 메시지를 처리하는 함수이다. 메시지를 보내는 측에서 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

    메시지의 블로킹 처리 여부를 결정한다.

    flags로 사용 가능한 값은 다음과 같다.

    • TPBLOCK

      tpgetunsol()을 호출할 때에 블로킹 상태로 일방적인 메시지가 올 때까지 기다린다.

    • TPNOCHANGE

      수신된 응답 버퍼와 *data가 가리키는 버퍼의 유형이 다르다면 *data의 버퍼 유형은 수신자가 인식할 수 있는 한도 내에서 수신된 응답 버퍼의 유형으로 변경된다.

      flags가 설정된 경우 *data가 가리키는 버퍼의 유형은 변경되지 못한다. 수신된 응답 버퍼의 유형 및 하위 유형은 *data가 가리키는 버퍼의 유형 및 하위 유형과 반드시 일치해야 한다.

    • TPNOTIME

      함수 호출자가 블록 타임아웃을 무시하고 응답이 수신될 때까지 무한정 기다리겠다는 것을 의미한다. 트랜잭션 모드에서 tpgetrply()를 수행한 경우에는 여전히 트랜잭션 타임아웃이 적용된다.

    • TPSIGRSTRT

      시그널(signal) 인터럽트를 수용하는 경우 사용한다. 시스템 함수 호출이 방해될 때 시스템 함수 호출이 재실행된다. 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()

클라이언트에서 사용되는 함수로 비요청 수신 메시지를 처리하는 루틴 설정한다. 시스템이 비요청 메시지를 통지받는 데 사용되는 방법은 애플리케이션에 임의로 결정되며, 이는 각 클라이언트별로 변경이 가능하다.

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()

클라이언트에서 사용되는 함수로 비요청 메시지 수신 flags를 변경한다. tpstart() 함수를 이용하여 Tmax 시스템과 연결할 때 사용한 flags 값을 재설정한다.

  • 프로토타입

    # include <atmi.h>
    int  tpsetunsol_flag  (int  flag)
  • 파라미터

    파라미터설명
    flag

    비요청 메시지를 수신과 관련된 flags로 설정한다. 다음 중 하나를 설정한다.

    • TPUNSOL_IGN : 비요청 메시지를 받지 않는다.

    • TPUNSOL_HND, TPUNSOL_POLL : 비요청 메시지를 받는다.

  • 반환값

    반환값설명
    1함수 호출에 성공한 경우이다.
    -1함수 호출에 실패한 경우이다. flag가 설정 가능한 3가지 중 하나가 아닌 경우로, 에러가 발생해도 tperrno에는 값이 설정되지 않는다.
  • 예제

    #include <stdio.h>
    #include <usrinc/atmi.h>
    #include “../sdl/demo.s”
    
    void get_unsol(char *, long, long);
    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, &buf, &len, TPNOFLAGS);
        if (ret==-1) { error processing }
        data process... 
    
        tpfree((char *)buf);
        tpend();
    }
    
    void get_unsol(char *, long, long);
    {
        printf(“get unsolicited data.\n”);
        data process....
    }
  • 관련 함수

    tpstart()