디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

러스트가 c 대체 불간응한 EU

나르시갤로그로 이동합니다. 2025.07.23 15:00:35
조회 60 추천 0 댓글 0

러스트로는 이런거 못 짠다. ㅎㅎㅎ

러빨러들한테 속지 마라


// -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*-

/*

  c-loop.c

  This file is part of Clair.

  Copyright (C) 2021-2025 Hodong Kim, All rights reserved.

  Unauthorized copying of this software, via any medium is strictly prohibited.

  Proprietary and confidential.

  Written by Hodong Kim <hodong@nimfsoft.art>

 */

#if defined(__FreeBSD__) || defined(__OpenBSD__)

  #include <sys/param.h>

  #include <sys/event.h>

  #ifdef __FreeBSD_version

    #if __FreeBSD_version >= 1400000

      #define __C_TIMER_FD__

      #include <sys/timerfd.h>

    #endif

  #endif

#elif defined(__linux__)

  #define _POSIX_C_SOURCE 199309L // CLOCK_MONOTONIC

  #define __C_TIMER_FD__

  #include <sys/timerfd.h>

  #include <sys/epoll.h>

#endif


#include "c-loop.h"

#include "c-mem.h"

#include <stdlib.h>

#include <unistd.h>

#include "c-log.h"

#include <errno.h>

#include <string.h>

#include <assert.h>


static CLoop* c_loop;


CSource* c_source_new ()

{

  CSource* source = c_calloc (1, sizeof (CSource));


  return source;

}


void c_source_free (CSource* source)

{

  free (source);

}


CLoop* c_loop_get_default ()

{

  if (!c_loop)

    c_loop = c_loop_new ();


  return c_loop;

}


static uintptr_t idle_key_hash (const uintptr_t* key, uint32_t seed)

{

  return c_murmur3_32 ((const uint8_t*) key, 2 * sizeof (uintptr_t), seed);

}


static bool idle_key_equal (const uintptr_t* a, const uintptr_t* b)

{

  return !memcmp (a, b, 2 * sizeof (uintptr_t));

}


static void idle_key_free (void* key)

{

  free (key);

}


CLoop* c_loop_new ()

{

#if defined(__FreeBSD__) || defined(__OpenBSD__)

  int fd = kqueue ();

#elif defined __linux__

  int fd = epoll_create1 (EPOLL_CLOEXEC);

#else

  #error "This platform is not supported"

#endif

  if (fd == -1)

  {

    c_log_warning ("%s", strerror (errno));

    return nullptr;

  }


  CLoop* loop = c_calloc (1, sizeof (CLoop));

  loop->timeout = -1;

  loop->timeout_idle = 250;

  loop->capa = 4;

#if defined(__FreeBSD__) || defined(__OpenBSD__)

  loop->kq = fd;

  loop->events = c_calloc (1, loop->capa * sizeof (struct kevent));

#elif defined __linux__

  loop->epfd = fd;

  loop->events = c_calloc (1, loop->capa * sizeof (struct epoll_event));

#else

  #error "This platform is not supported"

#endif

  loop->sources = c_hash_map_new (c_ptr_hash, c_ptr_equal, nullptr, nullptr);

  loop->idles   = c_hash_map_new ((CHashFunc)  idle_key_hash,

                                  (CEqualFunc) idle_key_equal,

                                  (CFreeFunc)  idle_key_free,

                                  nullptr);

  return loop;

}


void c_loop_free (CLoop* loop)

{

  if (!loop)

    return;


  c_hash_map_free (loop->idles);

  c_hash_map_free (loop->sources);

#if defined(__FreeBSD__) || defined(__OpenBSD__)

  free (loop->events);

  close (loop->kq);

#elif defined __linux__

  free (loop->events);

  close (loop->epfd);

#else

  #error "This platform is not supported"

#endif

  free (loop);

}


void c_loop_quit (CLoop* loop)

{

  loop->run = false;

}


int c_loop_iteration (CLoop* loop)

{

  loop->depth++;

  // dispatch pending events

  CHashMapIter iter;

  c_hash_map_iter_init (&iter, loop->sources);

  CSource* source;


  while (c_hash_map_iter_next (&iter, NULL, (void**) &source))

    if (source->pending && source->pending (source) && source->dispatch)

    {

      source->dispatch (source);

      loop->depth--;

      return 1;

    }


  int timeout;


  if (loop->idles && c_hash_map_size (loop->idles))

  {

    if (loop->timeout > -1)

      timeout = C_MIN (loop->timeout, loop->timeout_idle);

    else

      timeout = loop->timeout_idle;

  }

  else

  {

    timeout = loop->timeout;

  }


  int retval;


  do {

#if defined(__FreeBSD__) || defined(__OpenBSD__)

    struct timespec* ts;

    struct timespec ts2;

    if (timeout == -1)

    {

      ts = nullptr;

    }

    else

    {

      ts2.tv_sec  = timeout * 1000000 / 1000000000;

      ts2.tv_nsec = timeout * 1000000 % 1000000000;

      ts = &ts2;

    }


    loop->n_revents = kevent (loop->kq, nullptr, 0, loop->events, loop->n_events, ts);

#elif defined __linux__

    loop->n_revents = epoll_wait (loop->epfd, loop->events, loop->n_events, timeout);

#else

  #error "This platform is not supported"

#endif

    retval = loop->n_revents;

  } while (loop->n_revents == -1 && errno == EINTR && loop->run);


  while (loop->n_revents > 0)

  {

    loop->n_revents--;

    int i = loop->n_revents;

    short revents = 0;

#if defined(__FreeBSD__) || defined(__OpenBSD__)

    if (loop->events[i].flags & EV_EOF)

      revents |= POLLHUP;

    if (loop->events[i].flags & EV_ERROR)

      revents |= POLLERR;

    if (loop->events[i].filter == EVFILT_READ)

      revents |= POLLIN;

    else if (loop->events[i].filter == EVFILT_WRITE)

      revents |= POLLOUT;

#elif defined(__linux__)

    if (loop->events[i].events & EPOLLHUP)

      revents |= POLLHUP;

    if (loop->events[i].events & EPOLLERR)

      revents |= POLLERR;

    if (loop->events[i].events & EPOLLIN)

      revents |= POLLIN;

    else if (loop->events[i].events & EPOLLOUT)

      revents |= POLLOUT;

#else

  #error "This platform is not supported"

#endif

    if (revents)

    {

      if ((source = c_hash_map_lookup (loop->sources,

#if defined(__FreeBSD__) || defined(__OpenBSD__)

                                       C_INT_TO_VOIDP (loop->events[i].ident))))

#elif defined(__linux__)

                                       C_INT_TO_VOIDP (loop->events[i].data.fd))))

#else

  #error "This platform is not supported"

#endif

      {

        source->revents = revents;


        if (source->dispatch)

          source->dispatch (source);

      }

    }

  }


  if (loop->depth == 1 && loop->idles && c_hash_map_size (loop->idles))

  {

    uintptr_t* key;

    void* user_data;


    c_hash_map_iter_init (&iter, loop->idles);


    while (c_hash_map_iter_next (&iter, (void**) &key, &user_data))

    {

      CCallback1 callback = (CCallback1) key[0];

      callback (user_data);

    }

  }


  loop->depth--;

  return retval;

}


bool c_loop_run (CLoop* loop)

{

  loop->run = true;


  while (loop->run)

  {

    if (c_loop_iteration (loop) == -1)

    {

      if (errno == EINTR)

        c_log_info ("%s", strerror (errno));

      else

        c_log_critical ("%s", strerror (errno));


      return false;

    }

  }


  return true;

}


void c_loop_add_source (CLoop* loop, CSource* source)

{

  if (source->fd < 0)

  {

    c_log_warning ("c_loop_add_source failed: source->fd: %d", source->fd);

    return;

  }


#if defined(__FreeBSD__) || defined(__OpenBSD__)

  struct kevent kevents[2];

  int status;

  int n_events = 0;


  if (source->events & POLLIN)

  {

    EV_SET (&kevents[n_events], source->fd, EVFILT_READ, EV_ADD, 0, 0, 0);

    n_events++;

  }


  if (source->events & POLLOUT)

  {

    EV_SET (&kevents[n_events], source->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);

    n_events++;

  }


  status = kevent (loop->kq, kevents, n_events, NULL, 0, NULL);

  if (status == -1)

  {

    c_log_warning ("kevent (loop->kq, kevents, %d, NULL, 0, NULL) failed: %s",

                   n_events, strerror (errno));

    return;

  }

#elif defined __linux__

  struct epoll_event eevent = { 0 };

  int status;

  int n_events = 1;

  eevent.events = 0;

  eevent.data.fd = source->fd;


  if (source->events & POLLIN)

    eevent.events |= EPOLLIN;


  if (source->events & POLLOUT)

    eevent.events = EPOLLOUT;


  status = epoll_ctl (loop->epfd, EPOLL_CTL_ADD, source->fd, &eevent);

  if (status == -1)

  {

    c_log_warning ("epoll_ctl EPOLL_CTL_ADD %d  failed: %s",

                   source->fd, strerror (errno));

    return;

  }

#else

  #error "This platform is not supported"

#endif


#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__)

  loop->n_events += n_events;


  if (loop->n_events == loop->capa)

#else

  #error "This platform is not supported"

#endif

  {

    loop->capa *= 2;

#if defined(__FreeBSD__) || defined(__OpenBSD__)

    loop->events = c_realloc (loop->events,

                              loop->capa * sizeof (struct kevent));

#elif defined __linux__

    loop->events = c_realloc (loop->events,

                              loop->capa * sizeof (struct epoll_event));

#else

  #error "This platform is not supported"

#endif

  }


  c_hash_map_insert (loop->sources, C_INT_TO_VOIDP (source->fd), source);

}


void c_loop_remove_source (CLoop* loop, CSource* source)

{

  int status;

  int n_events = 0;

#if defined(__FreeBSD__) || defined(__OpenBSD__)

  struct kevent kevents[2];


  if (source->events & POLLIN)

  {

    EV_SET (&kevents[n_events], source->fd, EVFILT_READ, EV_DELETE, 0, 0, 0);

    n_events++;

  }


  if (source->events & POLLOUT)

  {

    EV_SET (&kevents[n_events], source->fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);

    n_events++;

  }


  status = kevent (loop->kq, kevents, n_events, NULL, 0, NULL);

  if (status == -1)

  {

    c_log_warning ("kevent (loop->kq, kevents, 1, NULL, 0, NULL) failed: %s",

                   strerror (errno));

    return;

  }


  for (int i = 0; i < loop->n_revents; i++)

  {

    if (loop->events[i].ident == source->fd)

    {

      loop->events[i].ident  = -1;

      loop->events[i].filter = 0;

      loop->events[i].flags  = 0;

    }

  }

#elif defined __linux__

  n_events = 1;


  status = epoll_ctl (loop->epfd, EPOLL_CTL_DEL, source->fd, nullptr);

  if (status == -1)

  {

    c_log_warning ("epoll_ctl EPOLL_CTL_DEL %d  failed: %s",

                   source->fd, strerror (errno));

    return;

  }


  for (int i = 0; i < loop->n_revents; i++)

  {

    if (loop->events[i].data.fd == source->fd)

    {

      loop->events[i].events  = 0;

      loop->events[i].data.fd = -1;

      break;

    }

  }

#else

  #error "This platform is not supported"

#endif


  loop->n_events -= n_events;


  if (loop->n_events < loop->capa / 4)

  {

    loop->capa /= 2;

#if defined(__FreeBSD__) || defined(__OpenBSD__)

    loop->events = c_realloc (loop->events,

                              loop->capa * sizeof (struct kevent));

#elif defined __linux__

    loop->events = c_realloc (loop->events,

                              loop->capa * sizeof (struct epoll_event));

#else

  #error "This platform is not supported"

#endif

  }


  c_hash_map_remove (loop->sources, C_INT_TO_VOIDP (source->fd));

}


static void fd_dispatch (CSource* source)

{

  if (source->callback)

  {

    CFdCallback callback = (CFdCallback) source->callback;

    callback (source->fd, source->revents, source->user_data);

  }

}


void c_loop_add_fd (CLoop*      loop,

                    int         fd,

                    short       events,

                    CFdCallback callback,

                    void*       user_data)

{

  if (fd < 0)

  {

    c_log_warning ("c_loop_add_fd failed: fd: %d", fd);

    return;

  }


  CSource* source   = c_source_new ();

  source->fd        = fd;

  source->events    = events;

  source->dispatch  = fd_dispatch;

  source->callback  = (CCallback) callback;

  source->user_data = user_data;

  c_loop_add_source (loop, source);

}


void c_loop_remove_fd (CLoop* loop, int fd)

{

  if (fd < 0)

  {

    c_log_warning ("c_loop_remove_fd failed: %d", fd);

    return;

  }


  CSource* source = c_hash_map_lookup (loop->sources, C_INT_TO_VOIDP (fd));

  c_loop_remove_source (loop, source);

  c_source_free (source);

}


void c_loop_mod_fd (CLoop* loop, int fd, short events)

{

  CSource* source = c_hash_map_lookup (loop->sources, C_INT_TO_VOIDP (fd));


#if defined(__FreeBSD__) || defined(__OpenBSD__)

  struct kevent kevents[2];

  int i = 0;


  if ((source->events & POLLIN) - (events & POLLIN) > 0)

  {

    EV_SET (&kevents[i], fd, EVFILT_READ, EV_DELETE, 0, 0, 0);

    i++;

  }

  else if ((source->events & POLLIN) - (events & POLLIN) < 0)

  {

    EV_SET (&kevents[i], fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, 0);

    i++;

  }


  if ((source->events & POLLOUT) - (events & POLLOUT) > 0)

  {

    EV_SET (&kevents[i], fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);

    i++;

  }

  else if ((source->events & POLLOUT) - (events & POLLOUT) < 0)

  {

    EV_SET (&kevents[i], fd, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, 0);

    i++;

  }


  if (i > 0)

  {

    int status = kevent (loop->kq, kevents, i, NULL, 0, NULL);

    if (status == -1)

    {

      c_log_warning ("kevent (loop->kq, kevents, i, NULL, 0, NULL) failed: %s",

                     i, strerror (errno));

    }

  }

#elif defined __linux__

  struct epoll_event eevent = { 0 };


  if (events & POLLIN)

    eevent.events = EPOLLIN;

  if (events & POLLOUT)

    eevent.events = EPOLLOUT;


  eevent.data.fd = fd;

  int status = epoll_ctl (loop->epfd, EPOLL_CTL_MOD, fd, &eevent);

  if (status == -1)

    c_log_warning ("epoll_ctl EPOLL_CTL_MOD %d %u failed: %s",

                   fd, eevent.events, strerror (errno));

#else

  #error "This platform is not supported"

#endif


  source->events = events;

}


void* c_loop_add_idle (CLoop* loop, CCallback1 callback, void* user_data)

{

  uintptr_t* key = c_malloc (2 * sizeof (uintptr_t));

  key[0] = (uintptr_t) callback;

  key[1] = (uintptr_t) user_data;

  c_hash_map_insert (loop->idles, key, user_data);

  return callback;

}


void c_loop_remove_idle (CLoop* loop, CCallback1 callback, void* user_data)

{

  uintptr_t key[2] = { (uintptr_t) callback, (uintptr_t) user_data };

  c_hash_map_remove (loop->idles, key);

}


static void timer_dispatch (CSource* source)

{

  c_log_debug ("timer_dispatch: source->fd: %d", source->fd);


  int status;


#if defined(__C_TIMER_FD__)

  uint64_t n_expirations;

  do {

    status = read (source->fd, &n_expirations, sizeof (uint64_t));

  } while (status == -1 && errno == EINTR);

#else

  struct kevent event;

  status = kevent (source->fd, NULL, 0, &event, 1, NULL);

#endif


  if (status == -1)

  {

    c_log_critical ("%s", strerror (errno));

    return;

  }

  else if (status > 0 && source->callback)

  {

    CCallback1 callback = (CCallback1) source->callback;

    callback (source->user_data);

  }


  return;

}


int c_loop_add_timer (CLoop* loop, int ms, CCallback1 callback, void* user_data)

{

#if defined(__C_TIMER_FD__)

  int fd = timerfd_create (CLOCK_MONOTONIC, TFD_CLOEXEC);

#else

  int fd = kqueue ();

#endif


  if (fd == -1)

  {

    c_log_warning ("%s", strerror (errno));

    return -1;

  }


  if (!c_loop_mod_timer (loop, fd, ms))

  {

    close (fd);

    return -1;

  }


  CSource* source   = c_source_new ();

  source->fd        = fd;

  source->events    = POLLIN;

  source->dispatch  = timer_dispatch;

  source->callback  = (CCallback) callback;

  source->user_data = user_data;

  c_loop_add_source (loop, source);


  return fd;

}


void c_loop_remove_timer (CLoop* loop, int fd)

{

  if (fd < 0)

  {

    c_log_warning ("fd is less than 0: i%d", fd);

    return;

  }


  CSource* source = c_hash_map_lookup (loop->sources, C_INT_TO_VOIDP (fd));


  if (source)

  {

#if defined(__C_TIMER_FD__)

    struct itimerspec ts = { { 0, 0 }, { 0, 0 } };

    if (timerfd_settime (fd, 0, &ts, nullptr))

      c_log_warning ("%s", strerror (errno));

#else

    struct kevent event;

    EV_SET (&event, fd, EVFILT_TIMER, EV_DELETE | EV_DISABLE, 0, 0, 0);

    int status = kevent (source->fd, &event, 1, NULL, 0, NULL);

    if (status == -1)

    {

      c_log_warning ("kevent (%d, &event, 1, NULL, 0, NULL) failed: %s", fd,

                     strerror (errno));

    }

#endif


    c_loop_remove_source (loop, source);

    c_source_free (source);


    if (fd > -1)

      close (fd);

  }

}


bool c_loop_mod_timer (CLoop* loop, int fd, int ms)

{

  if (fd < 0)

  {

    c_log_warning ("fd < 0: %d", fd);

    return false;

  }


#if defined(__C_TIMER_FD__)

  long nsec;


  if (ms > 0)

    nsec = (long) ms * 1000000;

  else if (ms == 0)

    nsec = 1;

  else

    nsec = 0;


  struct itimerspec its;

  // 1000000000 ns = 1 sec

  its.it_value.tv_sec     = nsec / 1000000000;

  its.it_value.tv_nsec    = nsec % 1000000000;

  its.it_interval.tv_sec  = its.it_value.tv_sec;

  its.it_interval.tv_nsec = its.it_value.tv_nsec;


  if (timerfd_settime (fd, 0, &its, nullptr))

  {

    c_log_warning ("timerfd_settime failed: %s", strerror (errno));

    return false;

  }

#else

  struct kevent event;

  int status;


  if (ms < 0)

    EV_SET (&event, fd, EVFILT_TIMER, EV_ADD | EV_DISABLE, 0, 0, 0);

  else

    EV_SET (&event, fd, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, ms, 0);


  status = kevent (fd, &event, 1, NULL, 0, NULL);

  if (status == -1)

  {

    c_log_warning ("kevent (fd, &event, 1, NULL, 0, NULL) failed: %s",

                   strerror (errno));

    return false;

  }

#endif


  return true;

}




추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 의외로 연애 못할 것 같은 연애 하수 스타는? 운영자 25/08/04 - -
공지 프로그래밍 갤러리 이용 안내 [92] 운영자 20.09.28 46145 65
2879330 점점 러스트 못하면 도태되는 세상이 되어가는 중 ㄷㄷㄷㄷ [1] 프갤러(218.154) 12:19 4 0
2879329 마귀의 괴담은 널리 퍼뜨려야 합니다. 프갤러(220.84) 12:05 14 0
2879328 아 회사컴 씨발 [2] 루도그담당(118.235) 12:04 28 0
2879327 자바쓰는이유는 딱 1가지 밖에없지 [3] 프갤러(121.174) 12:03 30 0
2879326 삭제했는데, 프리랜서라서 좆같다... [3] ㅆㅇㅆ(124.216) 11:59 35 0
2879325 Ada 프로그래밍 연재를 하니까 러스토커가 ㅁㅌ 나르시갤로그로 이동합니다. 11:52 7 0
2879323 봤을테니 삭제해둠. 대부분 내 코드지만 내 코드가 아니라서 [2] ㅆㅇㅆ(124.216) 11:40 49 0
2879322 ❤+❤+❤+ [2] 어린이노무현갤로그로 이동합니다. 11:37 21 0
2879320 흠.. 확실히 꿀잠잔날은 뭔가 땡기는게 없군 ♥냥덩이♥갤로그로 이동합니다. 11:28 7 0
2879319 결정력 없이 떠다닌 과거를 반성합니다. 프갤러(220.84) 11:21 13 0
2879318 김성태 "전한길·전광훈·신천지·통일교 모인 당 돼 버려…위헌정당 빌미" 발명도둑잡기갤로그로 이동합니다. 11:19 13 0
2879317 갑질좌파 강선우와 좌청래의 관계 ♥냥덩이♥갤로그로 이동합니다. 11:18 7 0
2879316 ❤✨☀⭐⚡☘⛩나님 시작합니당⛩☘⚡⭐☀✨❤ ♥냥덩이♥갤로그로 이동합니다. 11:11 8 0
2879315 꿀잠잔 나님의 두뇌는 지구생명체 1황이당 By 나님 [1] ♥냥덩이♥갤로그로 이동합니다. 11:10 12 0
2879314 근데 좀 궁금한게 분명히 GPT도 깃 최상급 프로그래머들 코드 다넣었을 [7] ㅆㅇㅆ(124.216) 11:07 57 0
2879313 죽은 자는 돌아오지 않아요. 프갤러(220.84) 11:07 16 0
2879312 모바일기기는 무조건 가벼워야 ♥냥덩이♥갤로그로 이동합니다. 11:05 9 0
2879311 근데 진짜 깃 최상급 코드들 보면 경이롭지 않냐? 지피티한테 뽑아달라해도 [4] ㅆㅇㅆ(124.216) 11:01 50 0
2879310 오래살기를 허락받지 못했었죠. 프갤러(220.84) 11:01 14 0
2879309 예전에도 말했지만 자바 개발자 연봉은 기술보단 범죄행위에서 비롯됩니다. 프갤러(218.154) 11:00 24 0
2879308 요새 내 코드 스타일 변화는 명세 짜두고 제네릭으로 패턴 연결해둠 ㅆㅇㅆ(124.216) 10:59 25 0
2879307 코드는 일단 짜놓고 [2] 루도그담당(211.184) 10:57 28 0
2879306 12시쯤 나가볼까요... 도리스아(220.74) 10:57 12 0
2879305 지능'만' 뛰어났을뿐인 마귀 xx진. 프갤러(220.84) 10:53 21 0
2879304 지피티 5는 제미나이보다는 우위, OPUS 4.1보다는 낮은 그런 느낌듯 ㅆㅇㅆ(124.216) 10:51 30 0
2879303 연쇄살인 조직폭력 관련자 220.84가 오늘 꼭 해야 할 일 발명도둑잡기갤로그로 이동합니다. 10:51 24 0
2879302 컴퓨터네트워크 선수과목 있음? 프갤러(118.217) 10:49 14 0
2879301 기초생활수급자 인생. 근데 솔직히 절반만 주셔도 되는데, 데이터복구에 도리스아(220.74) 10:49 14 0
2879300 좌폐아는 4050 아니더라도 모자른 잉여들밖에 없넹 [1] ♥냥덩이♥갤로그로 이동합니다. 10:48 12 0
2879299 뭔 자뻑이여 인간 코드보다 못하다는건데 ㅆㅇㅆ(124.216) 10:48 11 0
2879298 빈부격차 심한 사회에서 적은 사회보다 인기 많은 노래 특징 발명도둑잡기갤로그로 이동합니다. 10:43 14 0
2879296 "좋은데 갔으면 좋겠다" 이럽디다. 프갤러(220.84) 10:36 39 0
2879295 118.235 발명도둑잡기갤로그로 이동합니다. 10:35 14 0
2879294 지피티 류 코드의 문제점이 메모리를 한번에 올려 자꾸 ㅆㅇㅆ(124.216) 10:29 14 0
2879293 휴대용 레트로 콘솔 게임기 KNULLI 운영체제 부팅 스크린 발명도둑잡기갤로그로 이동합니다. 10:27 10 0
2879292 지피티 5 코드 전반적으로 맥락에 따른 코드 변화를 미묘하게 못잡아낸다. ㅆㅇㅆ(124.216) 10:27 17 0
2879291 왜 펌웨어랑 윈도우는 커서같은 툴이안나오는것임? 네오커헠(211.234) 10:23 22 0
2879290 지피티 5 써보는데 여전히 소스제네레이터보다 리플랙션쓰네 [1] ㅆㅇㅆ(124.216) 10:20 25 0
2879289 지피티 5로 코드 뱉어봤는데 여전히 좀 아쉽 ㅆㅇㅆ(124.216) 10:17 23 0
2879288 용산을 일주일에 1번은 기본으로 가네요. 도리스아(220.74) 10:08 17 0
2879287 왜 윾과장은 메시지를 쳐안읽는 걸까요? [1] 아스카영원히사랑해갤로그로 이동합니다. 10:03 24 0
2879286 마귀들이 무슨 조건으로 세팅했는지 보세요. 프갤러(220.84) 09:54 15 0
2879285 자바는 뭔가 일하고있다는 표시를 내는 언어임 [2] ㅇㅇ갤로그로 이동합니다. 09:53 38 0
2879284 프로그래밍 언어의 가치 평가에 대한 특정 관점에 대한 반박 나르시갤로그로 이동합니다. 09:47 34 0
2879283 ❤✨☀⭐⚡☘⛩나님 시작합니당⛩☘⚡⭐☀✨❤ ♥냥덩이♥갤로그로 이동합니다. 09:33 15 0
2879282 GPT-5가 좋은 게 뭐냐면 에이도비갤로그로 이동합니다. 09:32 44 0
2879281 gpt5.0 써봉사람들 평이 먼가 그저그런데? [2] 밀우갤로그로 이동합니다. 09:26 57 0
2879280 5가 여태 나온 모델 짬뽕해서 넣은건가 [3] 루도그담당(211.184) 09:20 47 0
2879279 저는 이 사회를 살아갈수가 없는 인간입니다. 프갤러(220.84) 09:20 23 0
뉴스 '첫, 사랑을 위하여' 염정아X박해준X최윤지X김민규, 스페셜 포스터 깜짝 공개! 디시트렌드 08.07
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2