// File: /workspace/github_c_makefile_star2_O0/PARKINHYO[P]BlackjackGame/shm/shm_client.c
// Function: main
int main()
{
  /* Shared Memory */
  key_t        keyShm;       /* Shared Memory Key */
  key_t        keySem;       /* Semapore Key */
  _ST_SHM        *pstShm1;      /* 공용 메모리 구조체 */
  char buffer[BUFFER_SIZE];
  /* Shared Memory의 키값을 생성한다. */
  keyShm = (key_t)60100;
  keySem = (key_t)60101;
  int id;
  struct sembuf mysem_open  = {0, -1, SEM_UNDO}; // 세마포어 얻기
  struct sembuf mysem_close = {0, 1, SEM_UNDO};  // 세마포어 돌려주기

  /* 공유 메모리 세그먼트를 연다 - 필요하면 만든다. */
  if( (gnShmID1 = shmget( keyShm, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666 )) == -1 )
  {
          printf("Shared memory segment exist - opening as client\n");
          /* Segment probably already exists - try as a client */
          if( (gnShmID1 = shmget( keyShm, SEGSIZE, 0 )) == -1 )
          {
                  perror("shmget");
                  exit(1);
          }
  }
  else
  {
          printf("Creating new shared memory segment\n");
  }

  /* 현재 프로세스에 공유 메모리 세그먼트를 연결한다. */
  if( (pstShm1 = (_ST_SHM *)shmat(gnShmID1, 0, 0)) == NULL )
  {
          perror("shmat");
          exit(1);
  }

  /* 공유 Semapore 세그먼트를 연다 - 필요하면 만든다. */
  if( (gnSemID1 = semget( keySem, 1, IPC_CREAT | IPC_EXCL | 0666 )) == -1 )
  {
          printf("Semapore segment exist - opening as client\n");
          /* Segment probably already exists - try as a client */
          if( (gnSemID1 = semget( keySem, 0, 0 )) == -1 )
          {
                  perror("semget");
                  exit(1);
          }
  }
  else
  {
          printf("Creating new semapore segment\n");
  }

  /* Signal 등록 */
  (void) signal (SIGINT, (void (*)()) set_shutdown);


  while(1) {

    printf("input \"start\" ==> ");
    /*start를 입력하면 게임시작*/
    fgets(buffer, BUFFER_SIZE, stdin);

    /* 공유메모리에 데이터 쓰기 */
    strncpy(pstShm1->data, buffer, BUFFER_SIZE);
    pstShm1->check = 1;
    /* server가 먼저 실행 */
    while(pstShm1->check);

    /******* 임계영역 *******/
    if( semop(gnSemID1, &mysem_open, 1) == -1 )
    {
           perror("semop");
           exit(1);
    }
    /* 쓴 데이터가 ‘quit’이면 while 문 벗어남 */
    if(!strncmp(pstShm1->data, "quit", 4)) {
       break;
    }

    /*몇번째 클라이언트 ID인지를 받아온다.*/
    strcpy(buffer, pstShm1->data);
    printf("recv: %s\n", buffer);
    semop(gnSemID1, &mysem_close, 1);
    /******* 임계영역 *******/
    id=buffer[0]-48;
    /*play_game 스레드 진입*/
    pthread_create(&threads[0], NULL, play_game, (void*)(intptr_t) id);
    /*스레드 종료 대기후 삭제*/
    pthread_join(threads[0], NULL);
    printf("game end!\n");

    /* shared memory & semapore del */
    printf("[SIGNAL] : Shared meory segment marked for deletion\n");
    shmctl( gnShmID2, IPC_RMID, 0 );
    printf("[SIGNAL] : Semapore segment marked for deletion\n");
    semctl( gnSemID2, IPC_RMID, 0 );

    break;
  }
  if(shmdt(pstShm1) == -1) {
     perror("shmdt failed");
     exit(1);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl $0x0, -0x4(%rbp)
movl $0xeac4, -0x8(%rbp)     # imm = 0xEAC4
movl $0xeac5, -0xc(%rbp)     # imm = 0xEAC5
movl 0x1393(%rip), %eax      # 0x3356
movl %eax, -0x4a(%rbp)
movw 0x138d(%rip), %ax       # 0x335a
movw %ax, -0x46(%rbp)
movl 0x1385(%rip), %eax      # 0x335c
movl %eax, -0x50(%rbp)
movw 0x137f(%rip), %ax       # 0x3360
movw %ax, -0x4c(%rbp)
movl -0x8(%rbp), %edi
movl $0x2c, %esi
movl $0x7b6, %edx            # imm = 0x7B6
callq 0x1130
movl %eax, 0x31f3(%rip)      # 0x51f0
cmpl $-0x1, %eax
jne 0x2042
leaq 0x1259(%rip), %rdi      # 0x3262
movb $0x0, %al
callq 0x1090
movl -0x8(%rbp), %edi
movl $0x2c, %esi
xorl %edx, %edx
callq 0x1130
movl %eax, 0x31cb(%rip)      # 0x51f0
cmpl $-0x1, %eax
jne 0x2040
leaq 0x1262(%rip), %rdi      # 0x3293
callq 0x1100
movl $0x1, %edi
callq 0x1160
jmp 0x2050
leaq 0x1251(%rip), %rdi      # 0x329a
movb $0x0, %al
callq 0x1090
movl 0x319a(%rip), %edi      # 0x51f0
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x1120
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
jne 0x2081
leaq 0x124c(%rip), %rdi      # 0x32be
callq 0x1100
movl $0x1, %edi
callq 0x1160
movl -0xc(%rbp), %edi
movl $0x1, %esi
movl $0x7b6, %edx            # imm = 0x7B6
callq 0x1030
movl %eax, 0x315b(%rip)      # 0x51f4
cmpl $-0x1, %eax
jne 0x20db
leaq 0x121f(%rip), %rdi      # 0x32c4
movb $0x0, %al
callq 0x1090
movl -0xc(%rbp), %edi
xorl %edx, %edx
movl %edx, %esi
callq 0x1030
movl %eax, 0x3136(%rip)      # 0x51f4
cmpl $-0x1, %eax
jne 0x20d9
leaq 0x1226(%rip), %rdi      # 0x32f0
callq 0x1100
movl $0x1, %edi
callq 0x1160
jmp 0x20e9
leaq 0x1215(%rip), %rdi      # 0x32f7
movb $0x0, %al
callq 0x1090
movl $0x2, %edi
leaq -0xbb5(%rip), %rsi      # 0x1540
callq 0x10b0
leaq 0x1215(%rip), %rdi      # 0x3316
movb $0x0, %al
callq 0x1090
leaq -0x40(%rbp), %rdi
movq 0x2ec5(%rip), %rax      # 0x4fd8
movq (%rax), %rdx
movl $0x20, %esi
callq 0x10a0
movq -0x18(%rbp), %rdi
addq $0xc, %rdi
leaq -0x40(%rbp), %rsi
movl $0x20, %edx
callq 0x1040
movq -0x18(%rbp), %rax
movl $0x1, (%rax)
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
je 0x214b
jmp 0x2140
movl 0x30a3(%rip), %edi      # 0x51f4
leaq -0x4a(%rbp), %rsi
movl $0x1, %edx
callq 0x1150
cmpl $-0x1, %eax
jne 0x217a
leaq 0xfad(%rip), %rdi       # 0x3118
callq 0x1100
movl $0x1, %edi
callq 0x1160
movq -0x18(%rbp), %rdi
addq $0xc, %rdi
leaq 0x11a0(%rip), %rsi      # 0x3329
movl $0x4, %edx
callq 0x1050
cmpl $0x0, %eax
jne 0x219d
jmp 0x2255
leaq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0xc, %rsi
callq 0x1060
leaq -0x40(%rbp), %rsi
leaq 0x1175(%rip), %rdi      # 0x332e
movb $0x0, %al
callq 0x1090
movl 0x302e(%rip), %edi      # 0x51f4
leaq -0x50(%rbp), %rsi
movl $0x1, %edx
callq 0x1150
movsbl -0x40(%rbp), %eax
subl $0x30, %eax
movl %eax, -0x44(%rbp)
movslq -0x44(%rbp), %rcx
leaq 0x2fe7(%rip), %rdi      # 0x51d0
xorl %eax, %eax
movl %eax, %esi
leaq -0x424(%rip), %rdx      # 0x1dd0
callq 0x10e0
movq 0x2fd0(%rip), %rdi      # 0x51d0
xorl %eax, %eax
movl %eax, %esi
callq 0x1170
leaq 0x1128(%rip), %rdi      # 0x3338
movb $0x0, %al
callq 0x1090
leaq 0xe6b(%rip), %rdi       # 0x3089
movb $0x0, %al
callq 0x1090
movl 0x2f65(%rip), %edi      # 0x5190
xorl %esi, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x10f0
leaq 0xe81(%rip), %rdi       # 0x30be
movb $0x0, %al
callq 0x1090
movl 0x2f4a(%rip), %edi      # 0x5194
xorl %edx, %edx
movl %edx, %esi
movb $0x0, %al
callq 0x1110
movq -0x18(%rbp), %rdi
callq 0x1070
cmpl $-0x1, %eax
jne 0x2279
leaq 0xf48(%rip), %rdi       # 0x31b2
callq 0x1100
movl $0x1, %edi
callq 0x1160
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq