디시인사이드 갤러리

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

갤러리 본문 영역

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

나르시갤로그로 이동합니다. 2025.07.23 15:00:35
조회 59 추천 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 46080 65
2878576 무조건 당첨되는 3만원 팁 freeboombox(112.167) 03:04 4 0
2878575 일본 업계는 코틀린 언급조차도 없네 프갤러(220.92) 03:02 5 0
2878571 컴퓨터 = 난로 뒷통수한방(1.213) 02:11 12 0
2878570 음기 충전 발명도둑잡기갤로그로 이동합니다. 02:10 15 0
2878569 DJ가 일찌감치 일본의 우경화를 예언한 근거는? 발명도둑잡기갤로그로 이동합니다. 01:38 10 0
2878566 지치고 힘든 너에게 해주고싶은 말 믕믕이갤로그로 이동합니다. 01:14 19 0
2878564 박효신이 직접 밝히는 노래 잘하는 방법 발명도둑잡기갤로그로 이동합니다. 01:05 13 0
2878563 실시간베스트 만화 "텔레비전" 보니 생각나는 예전 글 발명도둑잡기갤로그로 이동합니다. 01:01 10 0
2878562 故 이선균·송영규 나란히…고은별 "또 하나의 별이 지다" 발명도둑잡기갤로그로 이동합니다. 00:52 12 0
2878561 <착한 사나이> 한대서 생각나는 예전 글 발명도둑잡기갤로그로 이동합니다. 00:34 17 0
2878560 행동력이 없단 이유로 겪은 모진 핍박 프갤러(220.84) 00:23 18 0
2878558 틀리앙이 아마 프로그래밍 사이트중 수준은 젤 높을껄 [3] ㅆㅇㅆ(124.216) 08.05 52 0
2878557 rvizweb 써본 사람 있냐 ? 프갤러(211.217) 08.05 23 0
2878555 어쩔수없을 것이면 앞당겼어야 했겠지요. 프갤러(220.84) 08.05 24 0
2878554 "사랑은 움직이는 거야" 광고 보면 생각나는 예전 글 발명도둑잡기갤로그로 이동합니다. 08.05 17 0
2878553 장대호도 일베충이여서 숙청당한거임?? 뒷통수한방(1.213) 08.05 22 0
2878552 일베충들 왜 욕먹는거임 커뮤니티가 그렇개 많은데 뒷통수한방(1.213) 08.05 18 0
2878551 면목이 없으나 어쩔수없는 일이예요. 프갤러(220.84) 08.05 19 0
2878550 클리앙 vs okky 어디가 더 강하냐?? [1] 프갤러(1.213) 08.05 36 0
2878549 내가 잘 모르는 분야 발명도둑잡기갤로그로 이동합니다. 08.05 23 0
2878548 나는 프로그래밍에 재능없단 생각 항상 한다 [6] ㅆㅇㅆ(124.216) 08.05 72 0
2878547 간첩 [1] 발명도둑잡기갤로그로 이동합니다. 08.05 34 0
2878546 방금 인스타그램 추천에 방검폭 테스트 떴다 발명도둑잡기갤로그로 이동합니다. 08.05 15 0
2878545 오늘 더불어민주당 정청래 대표께서 진보당을 방문해주셨습니다 발명도둑잡기갤로그로 이동합니다. 08.05 16 0
2878544 <좀비 딸>이 히트했대서 생각나는 예전 글 발명도둑잡기갤로그로 이동합니다. 08.05 26 0
2878543 xx우가 호의를 베풀면 안됐습니다. [1] 프갤러(220.84) 08.05 30 0
2878542 정보통신과 대중심리 [1] 발명도둑잡기갤로그로 이동합니다. 08.05 30 0
2878537 나의 운명은 좇같은 인간새끼들 심판을 위해서 태어남 [5] 타이밍뒷통수한방(1.213) 08.05 46 0
2878536 네 소원이 무엇이냐고 하나님이 물으신다면 [16] ♥꽃보다냥덩♥갤로그로 이동합니다. 08.05 66 0
2878535 나님은 너희가 인생이란 숲속 길을 잃지 않게 도와주는 나침반이양⭐+ [12] ♥꽃보다냥덩♥갤로그로 이동합니다. 08.05 47 0
2878533 주변 사람들이 늙어가는게 눈에 보여 넘 슬프당.. [3] ♥꽃보다냥덩♥갤로그로 이동합니다. 08.05 40 0
2878532 중국산 칠판 발명도둑잡기갤로그로 이동합니다. 08.05 17 0
2878531 한남들 숨결이 피부에 닿을때 [6] 개멍청한유라갤로그로 이동합니다. 08.05 40 0
2878530 절 스토킹하는 악귀 군단이 붙은 건가요. 프갤러(220.84) 08.05 18 0
2878528 방금 집에왔어요 [3] 루도그담당(58.239) 08.05 38 0
2878527 좆기로 갈 생각 마라 [4] 밀우갤로그로 이동합니다. 08.05 57 0
2878526 영혼에 비수가 꽂혀 삶이 거꾸로갑니다 [1] 프갤러(220.84) 08.05 22 0
2878525 국비 it [3] 프갤러(220.86) 08.05 58 0
2878524 내 인생은 왜 이리 힘든가요 [5] 개멍청한유라갤로그로 이동합니다. 08.05 45 0
2878523 PL이 업무 이것도 모르냐는데 [4] 개멍청한유라갤로그로 이동합니다. 08.05 45 0
2878522 나는 무엇도 쟁취하지 못합니다. [1] 프갤러(220.84) 08.05 24 0
2878517 너무 배부르다 [3] 개멍청한유라갤로그로 이동합니다. 08.05 34 0
2878516 MSSQL은 마소 생태계라는 관점에서 봐야지 ㅆㅇㅆ(124.216) 08.05 31 0
2878515 나님 쉬야하구 쿨쿨⭐+ [1] ♥꽃보다냥덩♥갤로그로 이동합니다. 08.05 30 0
2878514 원종이는 감옥생활조차 서정적일듯.. [1] ♥꽃보다냥덩♥갤로그로 이동합니다. 08.05 40 0
2878513 한화시스템 부캠 어떰? 프갤러(183.102) 08.05 21 0
2878512 mssql는 진짜 개구린거같은데 [16] 밀우갤로그로 이동합니다. 08.05 85 0
2878511 내가 느끼는게 이제 내가 코드짜는거 의미가 없다 [2] ㅆㅇㅆ찡갤로그로 이동합니다. 08.05 42 0
2878510 가난이 밉다... 영화 싸게 봐보겠다고 할인쿠폰이나 찾아다니는 인생이.. [1] ㅇㅇ(223.39) 08.05 22 0
뉴스 최화정 사주풀이, 어떻게 보시나요? 디시트렌드 08.05
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2